aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Pfetsch <spfetsch@google.com>2016-05-03 12:49:49 -0700
committerSteve Pfetsch <spfetsch@google.com>2016-05-03 12:49:49 -0700
commit42408dde031eb14e0ebfa2a27993f01422f7de53 (patch)
tree99fa5fe0fee21d0edfbe44c9d31686e46299fb38
parent703c92069d9571adfc77eb3646654d3333d2c434 (diff)
parent452dd7ba0b1179321d1bea5b5a800d956378c05b (diff)
Merge AU_LINUX_ANDROID_LA.HB.1.3.9.06.00.01.213.156 into android-msm-marlin-3.18
Conflicts: arch/arm/mm/mmap.c drivers/gpu/msm/adreno_a5xx.c drivers/video/msm/mdss/msm_mdss_io_8974.c kernel/trace/trace_event_perf.c sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c Change-Id: I66e83a530e2314ab43fc5a4ed205662853418f98
-rw-r--r--Documentation/devicetree/bindings/arm/cpus.txt14
-rw-r--r--Documentation/devicetree/bindings/arm/msm/adv7481.txt20
-rw-r--r--Documentation/devicetree/bindings/arm/msm/msm_thermal.txt7
-rw-r--r--Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt7
-rw-r--r--Documentation/devicetree/bindings/fb/mdss-mdp.txt14
-rw-r--r--Documentation/devicetree/bindings/gpu/adreno.txt22
-rw-r--r--Documentation/devicetree/bindings/pci/msm_pcie.txt4
-rw-r--r--Documentation/devicetree/bindings/regulator/cpr3-regulator.txt13
-rw-r--r--Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt7
-rw-r--r--Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt6
-rw-r--r--Documentation/scheduler/sched-zone.txt19
-rw-r--r--arch/arm/boot/dts/qcom/Makefile3
-rw-r--r--arch/arm/boot/dts/qcom/apq8096-sbc.dtsi11
-rw-r--r--arch/arm/boot/dts/qcom/apq8096-v3-pmi8996-mdm9x55-i2s-mtp.dts150
-rw-r--r--arch/arm/boot/dts/qcom/mdm9607.dtsi32
-rw-r--r--arch/arm/boot/dts/qcom/mdmcalifornium-nand-dualwifi-mtp.dts31
-rw-r--r--arch/arm/boot/dts/qcom/mdmcalifornium-pinctrl.dtsi6
-rw-r--r--arch/arm/boot/dts/qcom/mdmcalifornium.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmi8937.dtsi13
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmi8950.dtsi12
-rw-r--r--arch/arm/boot/dts/qcom/msm8917-pmi8937-qrd-sku5.dts2
-rw-r--r--arch/arm/boot/dts/qcom/msm8917-qgp-tmo.dtsi37
-rw-r--r--arch/arm/boot/dts/qcom/msm8917-regulator.dtsi6
-rw-r--r--arch/arm/boot/dts/qcom/msm8917.dtsi7
-rw-r--r--arch/arm/boot/dts/qcom/msm8937-cdp.dtsi5
-rw-r--r--arch/arm/boot/dts/qcom/msm8937-coresight.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm8937-gpu.dtsi15
-rw-r--r--arch/arm/boot/dts/qcom/msm8937-mdss.dtsi10
-rw-r--r--arch/arm/boot/dts/qcom/msm8937-mtp.dtsi5
-rw-r--r--arch/arm/boot/dts/qcom/msm8937-regulator.dtsi8
-rw-r--r--arch/arm/boot/dts/qcom/msm8937.dtsi191
-rw-r--r--arch/arm/boot/dts/qcom/msm8940-pmi8950-ext-codec-cdp.dts102
-rw-r--r--arch/arm/boot/dts/qcom/msm8940-pmi8950-qrd-sku6.dts2
-rw-r--r--arch/arm/boot/dts/qcom/msm8940.dtsi294
-rw-r--r--arch/arm/boot/dts/qcom/msm8953-gpu.dtsi11
-rw-r--r--arch/arm/boot/dts/qcom/msm8953-mdss.dtsi10
-rw-r--r--arch/arm/boot/dts/qcom/msm8953-regulator.dtsi25
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-camera.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-cdp.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-gpu.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-mtp.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi74
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-pm.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts18
-rw-r--r--arch/arm/boot/dts/qcom/msm8996pro.dtsi35
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi2
-rw-r--r--arch/arm/configs/mdm-perf_defconfig3
-rw-r--r--arch/arm/configs/mdm9607-perf_defconfig2
-rw-r--r--arch/arm/configs/mdm9607_defconfig2
-rw-r--r--arch/arm/configs/mdm_defconfig3
-rw-r--r--arch/arm/configs/msm8937-perf_defconfig5
-rw-r--r--arch/arm/configs/msm8937_defconfig5
-rw-r--r--arch/arm/kernel/topology.c34
-rw-r--r--arch/arm/mm/mmap.c5
-rw-r--r--arch/arm64/configs/msm-auto-perf_defconfig2
-rw-r--r--arch/arm64/configs/msm-auto_defconfig2
-rw-r--r--arch/arm64/configs/msm-perf_defconfig2
-rw-r--r--arch/arm64/configs/msm8937-perf_defconfig3
-rw-r--r--arch/arm64/configs/msm8937_defconfig3
-rw-r--r--arch/arm64/configs/msm_defconfig2
-rw-r--r--arch/arm64/configs/msmcortex-perf_defconfig1
-rw-r--r--arch/arm64/configs/msmcortex_defconfig1
-rw-r--r--arch/arm64/kernel/topology.c30
-rw-r--r--drivers/base/dma-removed.c5
-rw-r--r--drivers/bluetooth/bluetooth-power.c2
-rw-r--r--drivers/char/adsprpc.c31
-rw-r--r--drivers/clk/msm/clock-gcc-8996.c6
-rw-r--r--drivers/cpuidle/lpm-levels-of.c160
-rw-r--r--drivers/cpuidle/lpm-levels.c47
-rw-r--r--drivers/cpuidle/lpm-levels.h7
-rw-r--r--drivers/devfreq/governor_spdm_bw_hyp.c6
-rw-r--r--drivers/edac/edac_device.c4
-rw-r--r--drivers/gpu/msm/adreno_a5xx.c1
-rw-r--r--drivers/gpu/msm/kgsl_cmdbatch.c39
-rw-r--r--drivers/gpu/msm/kgsl_sharedmem.c16
-rw-r--r--drivers/input/touchscreen/gt9xx/goodix_tool.c6
-rw-r--r--drivers/input/touchscreen/gt9xx/gt9xx.c15
-rw-r--r--drivers/input/touchscreen/gt9xx/gt9xx.h6
-rw-r--r--drivers/input/touchscreen/gt9xx/gt9xx_update.c4
-rw-r--r--drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c50
-rw-r--r--drivers/irqchip/irq-gic-v3.c3
-rw-r--r--drivers/media/i2c/Makefile4
-rw-r--r--drivers/media/i2c/adv7481.c1337
-rw-r--r--drivers/media/i2c/adv7481_reg.h434
-rw-r--r--drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c32
-rw-r--r--drivers/media/platform/msm/camera_v2/common/cam_soc_api.c26
-rw-r--r--drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c26
-rw-r--r--drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h1
-rw-r--r--drivers/media/platform/msm/camera_v2/fd/msm_fd_hw.c47
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c8
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp.h1
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp46.c2
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp47.c4
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c271
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c7
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c77
-rw-r--r--drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c4
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c6
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c2
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c2
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c2
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c4
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c33
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c8
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c8
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c14
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c6
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c54
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c6
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c2
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c6
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c18
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c43
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c12
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c4
-rw-r--r--drivers/media/platform/msm/vidc/hfi_response_handler.c14
-rw-r--r--drivers/media/platform/msm/vidc/msm_venc.c11
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c1
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.c53
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_internal.h1
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.c22
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_api.h1
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_helper.h7
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_io.h5
-rw-r--r--drivers/misc/qseecom.c9
-rw-r--r--drivers/mmc/core/mmc.c7
-rw-r--r--drivers/mtd/ubi/attach.c17
-rw-r--r--drivers/mtd/ubi/io.c12
-rw-r--r--drivers/mtd/ubi/ubi.h1
-rw-r--r--drivers/mtd/ubi/wl.c1
-rw-r--r--drivers/net/wireless/cnss/Kconfig23
-rw-r--r--drivers/net/wireless/cnss/Makefile4
-rw-r--r--drivers/net/wireless/cnss/cnss_common.c163
-rw-r--r--drivers/net/wireless/cnss/cnss_pci.c222
-rw-r--r--drivers/net/wireless/cnss/cnss_sdio.c118
-rw-r--r--drivers/pci/host/pci-msm.c39
-rw-r--r--drivers/platform/msm/ipa/ipa_api.c26
-rw-r--r--drivers/platform/msm/ipa/ipa_api.h4
-rw-r--r--drivers/platform/msm/ipa/ipa_clients/ipa_usb.c101
-rw-r--r--drivers/platform/msm/ipa/ipa_clients/odu_bridge.c83
-rw-r--r--drivers/platform/msm/ipa/ipa_common_i.h10
-rw-r--r--drivers/platform/msm/ipa/ipa_rm.c22
-rw-r--r--drivers/platform/msm/ipa/ipa_rm_i.h27
-rw-r--r--drivers/platform/msm/ipa/ipa_rm_resource.c42
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_dp.c4
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c5
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_utils.c15
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa.c11
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_client.c3
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c45
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_dma.c52
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_dp.c26
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c67
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_hw_defs.h39
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_i.h48
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c13
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c123
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c24
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h34
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_utils.c17
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c274
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h35
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h124
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c1
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c48
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c16
-rw-r--r--drivers/power/power_supply_sysfs.c1
-rw-r--r--drivers/power/qcom/apm.c14
-rw-r--r--drivers/power/qcom/msm-core.c15
-rw-r--r--drivers/power/qpnp-smbcharger.c49
-rw-r--r--drivers/regulator/cpr-regulator.c14
-rw-r--r--drivers/regulator/cpr3-regulator.c47
-rw-r--r--drivers/regulator/cpr3-regulator.h34
-rw-r--r--drivers/regulator/cpr3-util.c70
-rw-r--r--drivers/soc/qcom/bam_dmux.c12
-rw-r--r--drivers/soc/qcom/pil-q6v5.c2
-rw-r--r--drivers/soc/qcom/qdsp6v2/apr_tal_glink.c30
-rw-r--r--drivers/soc/qcom/subsystem_restart.c4
-rw-r--r--drivers/soundwire/soundwire.c37
-rw-r--r--drivers/soundwire/swr-wcd-ctrl.c72
-rw-r--r--drivers/soundwire/swr-wcd-ctrl.h3
-rw-r--r--drivers/thermal/msm_thermal.c55
-rw-r--r--drivers/usb/core/hcd.c6
-rw-r--r--drivers/usb/core/hub.c4
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c63
-rw-r--r--drivers/usb/gadget/Makefile2
-rw-r--r--drivers/usb/gadget/function/f_accessory.c6
-rw-r--r--drivers/usb/gadget/function/f_fs.c8
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.c1
-rw-r--r--drivers/usb/gadget/function/f_qdss.c23
-rw-r--r--drivers/usb/gadget/function/f_rndis.c2
-rw-r--r--drivers/usb/gadget/function/f_serial.c7
-rw-r--r--drivers/usb/host/ehci-hcd.c8
-rw-r--r--drivers/usb/host/ehci-hub.c19
-rw-r--r--drivers/usb/host/ehci-msm-hsic.c124
-rw-r--r--drivers/usb/host/xhci-plat.c9
-rw-r--r--drivers/usb/host/xhci.c4
-rw-r--r--drivers/video/msm/mdss/mdss.h6
-rw-r--r--drivers/video/msm/mdss/mdss_debug.c3
-rw-r--r--drivers/video/msm/mdss/mdss_dsi.c6
-rw-r--r--drivers/video/msm/mdss/mdss_dsi.h3
-rw-r--r--drivers/video/msm/mdss/mdss_dsi_clk.c28
-rw-r--r--drivers/video/msm/mdss/mdss_dsi_clk.h17
-rw-r--r--drivers/video/msm/mdss/mdss_dsi_host.c6
-rw-r--r--drivers/video/msm/mdss/mdss_dsi_panel.c5
-rw-r--r--drivers/video/msm/mdss/mdss_fb.c8
-rw-r--r--drivers/video/msm/mdss/mdss_hdmi_edid.c18
-rw-r--r--drivers/video/msm/mdss/mdss_hdmi_edid.h3
-rw-r--r--drivers/video/msm/mdss/mdss_hdmi_tx.c259
-rw-r--r--drivers/video/msm/mdss/mdss_hdmi_tx.h2
-rw-r--r--drivers/video/msm/mdss/mdss_hdmi_util.c24
-rw-r--r--drivers/video/msm/mdss/mdss_mdp.c100
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_ctl.c12
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_layer.c2
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_overlay.c22
-rw-r--r--drivers/video/msm/mdss/mdss_panel.h1
-rw-r--r--drivers/video/msm/mdss/msm_mdss_io_8974.c52
-rw-r--r--drivers/video/msm/msm_dba/adv7533.c6
-rw-r--r--include/dt-bindings/clock/msm-clocks-8996.h3
-rw-r--r--include/linux/diagchar.h9
-rw-r--r--include/linux/ipa.h6
-rw-r--r--include/linux/memblock.h4
-rw-r--r--include/linux/msm_thermal.h4
-rw-r--r--include/linux/power_supply.h1
-rw-r--r--include/linux/qdsp6v2/apr_tal.h1
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/sched/sysctl.h1
-rw-r--r--include/linux/soundwire/soundwire.h5
-rw-r--r--include/linux/usb/hcd.h3
-rw-r--r--include/linux/usb/msm_hsusb.h2
-rw-r--r--include/net/cnss.h4
-rw-r--r--include/uapi/linux/videodev2.h14
-rw-r--r--include/uapi/media/msm_camsensor_sdk.h1
-rw-r--r--include/uapi/media/msm_vidc.h5
-rw-r--r--kernel/power/qos.c26
-rw-r--r--kernel/sched/core.c1
-rw-r--r--kernel/sched/fair.c57
-rw-r--r--kernel/sysctl.c9
-rw-r--r--kernel/trace/trace_event_perf.c4
-rw-r--r--mm/memblock.c16
-rw-r--r--net/ipc_router/ipc_router_core.c15
-rw-r--r--net/netfilter/xt_qtaguid.c150
-rw-r--r--net/rmnet_data/rmnet_data_handlers.c6
-rw-r--r--net/wireless/reg.c18
-rw-r--r--net/xfrm/xfrm_input.c3
-rw-r--r--sound/soc/codecs/audio-ext-clk.c90
-rw-r--r--sound/soc/codecs/msm8x16-wcd.c48
-rw-r--r--sound/soc/codecs/wcd9335.c119
-rw-r--r--sound/soc/codecs/wsa881x-analog.c24
-rw-r--r--sound/soc/codecs/wsa881x.c8
-rw-r--r--sound/soc/msm/msm8952-dai-links.c2
-rw-r--r--sound/soc/msm/msm8996.c9
-rw-r--r--sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c24
-rwxr-xr-xsound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c64
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h10
-rw-r--r--sound/usb/card.c2
256 files changed, 6058 insertions, 2402 deletions
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index e6c12d4f9741..297a1835a921 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -210,6 +210,20 @@ nodes to be present and contain the properties described below.
property identifying a 64-bit zero-initialised
memory location.
+ - efficiency
+ Usage: optional.
+ Value type: <u32>
+ Definition:
+ # Specifies the CPU efficiency. The CPU efficiency is
+ a unit less number and it is intended to show relative
+ performance of CPUs when normalized for clock frequency
+ (instructions per cycle performance).
+
+ The efficiency of a CPU can vary across SoCs depending
+ on the cache size, bus interconnect frequencies etc.
+ This value overrides the default efficiency value
+ defined for the corresponding CPU architecture.
+
- qcom,saw
Usage: required for systems that have an "enable-method"
property value of "qcom,kpss-acc-v1" or
diff --git a/Documentation/devicetree/bindings/arm/msm/adv7481.txt b/Documentation/devicetree/bindings/arm/msm/adv7481.txt
new file mode 100644
index 000000000000..ea5fc3025fe2
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/adv7481.txt
@@ -0,0 +1,20 @@
+ADV7481 chip driver (VIDEO_ADV7481)
+
+VIDEO_ADV7481 is a kernel platform driver that is used for video decoder
+and dual mode HDMI/MHL receiver.
+
+The devicetree representation of the VIDEO_ADV7481 block should be:
+
+Required properties
+
+- compatible: "qcom,adv7481"
+- qcom,slave-addr: The i2c slave address of adv7481 driver.
+- qcom,cci-master: The i2c master id to be used for adv7481 driver.
+
+Example:
+
+ qcom,adv7481@0 {
+ compatible = "qcom,adv7481";
+ qcom,cci-master = <0>;
+ qcom,slave-addr = <0x70>;
+ };
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
index e6be8e7e25b7..f7af14b1343d 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
@@ -224,6 +224,12 @@ Optional child nodes
qcom,mx-restriction-temp and qcom,mx-restriction-temp-hysteresis
should also be present. Also, if this property is defined, will
have to define vdd-cx-supply = <&phandle_of_regulator>.
+- qcom,mx-restriction-sensor_id: sensor id, which needs to be monitored for requesting MX/CX
+ retention voltage. If this optional property is defined, msm_thermal
+ will monitor only this sensor, otherwise by default it will monitor
+ all TSENS for this feature. If this property exists, then the properties,
+ qcom,mx-restriction-temp, qcom,mx-restriction-temp-hysteresis and
+ qcom,mx-retention-min should also be defined to enable this feature.
- qcom,therm-reset-temp: Degree above which the KTM will initiate a secure watchdog reset.
When this property is defined, KTM will monitor all the tsens from
boot time and will initiate a secure watchdog reset if any of the
@@ -269,6 +275,7 @@ Example:
qcom,mx-restriction-temp = <5>;
qcom,mx-restriction-temp-hysteresis = <10>;
qcom,mx-retention-min = <710000>;
+ qcom,mx-restriction-sensor_id = <2>;
vdd-mx-supply = <&pma8084_s1>;
qcom,cx-retention-min = <RPM_SMD_REGULATOR_LEVEL_RETENTION_PLUS>;
vdd-cx-supply = <&pmd9635_s5_level>;
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
index b2c9a24aca7d..50402892a9b0 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
@@ -416,7 +416,11 @@ Optional properties:
fields in the supply entry, refer to the qcom,ctrl-supply-entries
binding above.
- qcom,config-select: Optional property to select default configuration.
-
+- qcom,panel-allow-phy-poweroff: A boolean property indicates that panel allows to turn off the phy power
+ supply during idle screen. A panel should able to handle the dsi lanes
+ in floating state(not LP00 or LP11) to turn on this property. Software
+ turns off PHY pmic power supply, phy ldo and DSI Lane ldo during
+ idle screen (footswitch control off) when this property is enabled.
[[Optional config sub-nodes]] These subnodes provide different configurations for a given same panel.
Default configuration can be chosen by specifying phandle of the
selected subnode in the qcom,config-select.
@@ -602,6 +606,7 @@ Example:
qcom,suspend-ulps-enabled;
qcom,panel-roi-alignment = <4 4 2 2 20 20>;
qcom,esd-check-enabled;
+ qcom,panel-allow-phy-poweroff;
qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 02 0A 08];
qcom,mdss-dsi-panel-status-command-state = "dsi_lp_mode";
qcom,mdss-dsi-panel-status-check-mode = "reg_read";
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index 949ecc6bcea4..c6eae2af4067 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -528,6 +528,10 @@ Fudge Factors: Fudge factors are used to boost demand for
- qcom,mdss-rot-reg-bus: Property to provide Bus scaling for register access for
Rotator Block.
+- qcom,mdss-hw-rt: Optional Property to request min vote on the bus.
+ Few Low tier targets expect min vote on the bus during SMMU
+ and TZ operations. use this handle to request the vote needed.
+
Optional subnodes:
- mdss_fb: Child nodes representing the frame buffer virtual devices.
@@ -838,6 +842,16 @@ Example:
<1 590 0 320000>;
};
+ qcom,mdss-hw-rt-bus {
+ /* hw-rt Bus Scale Settings */
+ qcom,msm-bus,name = "mdss_hw_rt";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <22 512 0 0>,
+ <22 512 0 1000>;
+ };
+
smmu_mdp_sec: qcom,smmu_mdp_sec_cb {
compatible = "qcom,smmu_mdp_sec";
iommus = <&mdp_smmu 1>;
diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt
index e55e64eea1ea..216076c52526 100644
--- a/Documentation/devicetree/bindings/gpu/adreno.txt
+++ b/Documentation/devicetree/bindings/gpu/adreno.txt
@@ -130,6 +130,19 @@ Optional Properties:
rendering thread is running on masked CPUs.
Bit 0 is for CPU-0, bit 1 is for CPU-1...
+- qcom,snapshot-size:
+ Specify the size of snapshot in bytes. This will override
+ snapshot size defined in the driver code.
+
+- qcom,enable-ca-jump:
+ Boolean. Enables use of context aware DCVS
+- qcom,ca-busy-penalty:
+ This property represents the time in microseconds required to
+ initiate context aware power level jump.
+- qcom,ca-target-pwrlevel:
+ This value indicates which qcom,gpu-pwrlevel to jump on in case
+ of context aware power level jump.
+
GPU Quirks:
- qcom,gpu-quirk-two-pass-use-wfi:
Signal the GPU to set Set TWOPASSUSEWFI bit in
@@ -207,6 +220,15 @@ Example of A330 GPU in MSM8916:
coresight-child-list = <&funnel_in0>;
coresight-child-ports = <5>;
+ /* Enable context aware freq. scaling */
+ qcom,enable-ca-jump;
+
+ /* Context aware jump busy penalty in us */
+ qcom,ca-busy-penalty = <12000>;
+
+ /* Context aware jump target power level */
+ qcom,ca-target-pwrlevel = <1>;
+
/* Power levels */
qcom,gpu-pwrlevels-bins {
#address-cells = <1>;
diff --git a/Documentation/devicetree/bindings/pci/msm_pcie.txt b/Documentation/devicetree/bindings/pci/msm_pcie.txt
index 34480b77670d..d4f566bcf3c0 100644
--- a/Documentation/devicetree/bindings/pci/msm_pcie.txt
+++ b/Documentation/devicetree/bindings/pci/msm_pcie.txt
@@ -91,6 +91,10 @@ Optional Properties:
from the endpoint.
- linux,pci-domain: For details of pci-domains properties, please refer to:
"Documentation/devicetree/bindings/pci/pci.txt"
+ - qcom,perst-delay-us-min: The minimum allowed time (unit: us) to sleep after
+ asserting or de-asserting PERST GPIO.
+ - qcom,perst-delay-us-max: The maximum allowed time (unit: us) to sleep after
+ asserting or de-asserting PERST GPIO.
- qcom,tlp-rd-size: The max TLP read size (Calculation: 128 times 2 to the
tlp-rd-size power).
- Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for
diff --git a/Documentation/devicetree/bindings/regulator/cpr3-regulator.txt b/Documentation/devicetree/bindings/regulator/cpr3-regulator.txt
index 0a5ad543a2be..7d88e9fbd9c6 100644
--- a/Documentation/devicetree/bindings/regulator/cpr3-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/cpr3-regulator.txt
@@ -183,6 +183,19 @@ Platform independent properties:
This is the voltage that vdd-supply must be set to when
performing an aging measurement.
+- qcom,cpr-panic-reg-addr-list
+ Usage: optional
+ Value type: <prop-encoded-array>
+ Definition: Array of register addresses to be dumped when device resets.
+
+- qcom,cpr-panic-reg-name-list
+ Usage: optional, though only meaningful if
+ qcom,cpr-panic-reg-addr-list is specified
+ Value type: <prop-encoded-array>
+ Definition: Address names. Must be specified in the same order
+ as the corresponding addresses are specified in
+ the qcom,cpr-panic-reg-addr-list property.
+
=================================================
Second Level Nodes - CPR Threads for a Controller
=================================================
diff --git a/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt b/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt
index 454fa3a4c071..29bb2d32bf91 100644
--- a/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt
@@ -407,6 +407,13 @@ apc_cpr: cpr4-ctrl@b018000 {
qcom,cpr-step-quot-fixed = <16>;
qcom,cpr-voltage-settling-time = <1600>;
+ qcom,cpr-panic-reg-addr-list =
+ <0xb1d2c18 0xb1d2900 0x0b1112b0 0xb018798>;
+ qcom,cpr-panic-reg-name-list =
+ "CCI_SAW4_PMIC_STS", "CCI_SAW4_VCTL",
+ "APCS_ALIAS0_APM_CTLER_STATUS",
+ "APCS0_CPR_CORE_ADJ_MODE_REG";
+
thread@0 {
qcom,cpr-thread-id = <0>;
qcom,cpr-consecutive-up = <1>;
diff --git a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
index 48cc084de720..e5304f8852f9 100644
--- a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
@@ -47,12 +47,6 @@ Optional properties :
- hsic,resume-gpio : if present then periperal connected to hsic controller
cannot wakeup from XO shutdown using in-band hsic resume. Use resume
gpio to wakeup peripheral
-- hsic,ignore-cal-pad-config : If present then HSIC CAL PAD configuration
- using TLMM is not performed.
-- hsic,strobe-pad-offset : Offset of TLMM register for configuring HSIC
- STROBE GPIO PAD.
-- hsic,data-pad-offset : Offset of TLMM register for configuring HSIC
- DATA GPIO PAD.
- qcom,phy-sof-workaround : If present then HSIC PHY has h/w BUGs related to
SOFs. All the relevant software workarounds are required for the same during
suspend, reset and resume.
diff --git a/Documentation/scheduler/sched-zone.txt b/Documentation/scheduler/sched-zone.txt
index 253391be357c..6a8dc675bf47 100644
--- a/Documentation/scheduler/sched-zone.txt
+++ b/Documentation/scheduler/sched-zone.txt
@@ -1293,7 +1293,7 @@ categorized as small wakee tasks. Scheduler places small wakee tasks on the
waker's cluster.
-*** 7.26 sched_big_waker_task_load
+*** 7.27 sched_big_waker_task_load
Appears at: /proc/sys/kernel/sched_big_waker_task_load
@@ -1303,6 +1303,23 @@ This tunable is a percentage. Configure the minimum demand of big sync waker
task. Scheduler places small wakee tasks woken up by big sync waker on the
waker's cluster.
+*** 7.28 sched_prefer_sync_wakee_to_waker
+
+Appears at: /proc/sys/kernel/sched_prefer_sync_wakee_to_waker
+
+Default value: 0
+
+The default sync wakee policy has a preference to select an idle CPU in the
+waker cluster compared to the waker CPU running only 1 task. By selecting
+an idle CPU, it eliminates the chance of waker migrating to a different CPU
+after the wakee preempts it. This policy is also not susceptible to the
+incorrect "sync" usage i.e the waker does not goto sleep after waking up
+the wakee.
+
+However LPM exit latency associated with an idle CPU outweigh the above
+benefits on some targets. When this knob is turned on, the waker CPU is
+selected if it has only 1 runnable task.
+
=========================
8. HMP SCHEDULER TRACE POINTS
=========================
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 1a1a3b8a2f1d..b641a42c7f8a 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -154,7 +154,8 @@ dtb-$(CONFIG_ARCH_MSM8940) += msm8940-pmi8937-cdp.dtb \
msm8940-pmi8950-mtp.dtb \
msm8940-pmi8937-rcm.dtb \
msm8940-pmi8950-rcm.dtb \
- msm8940-pmi8950-qrd-sku6.dtb
+ msm8940-pmi8950-qrd-sku6.dtb \
+ msm8940-pmi8950-ext-codec-cdp.dtb
dtb-$(CONFIG_ARCH_MSM8953) += msm8953-sim.dtb \
msm8953-rumi.dtb \
diff --git a/arch/arm/boot/dts/qcom/apq8096-sbc.dtsi b/arch/arm/boot/dts/qcom/apq8096-sbc.dtsi
index 3ab4b5714eee..fce4c0a2cb42 100644
--- a/arch/arm/boot/dts/qcom/apq8096-sbc.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8096-sbc.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -330,8 +330,8 @@
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,mdss-dsi-bl-pmic-pwm-frequency = <50>;
qcom,mdss-dsi-bl-pmic-bank-select = <0>;
- qcom,mdss-dsi-pwm-gpio = <&pm8994_gpios 6 0>;
- qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-pwm-gpio = <&pm8994_gpios 5 0>;
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply_no_labibb>;
};
&mdss_mdp {
@@ -363,12 +363,11 @@
};
&labibb {
- status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ status = "disabled";
};
&ibb_regulator {
- qcom,qpnp-ibb-discharge-resistor = <32>;
+ status = "disabled";
};
&rpm_bus {
diff --git a/arch/arm/boot/dts/qcom/apq8096-v3-pmi8996-mdm9x55-i2s-mtp.dts b/arch/arm/boot/dts/qcom/apq8096-v3-pmi8996-mdm9x55-i2s-mtp.dts
index 3e4d11122e01..599115d6e4a0 100644
--- a/arch/arm/boot/dts/qcom/apq8096-v3-pmi8996-mdm9x55-i2s-mtp.dts
+++ b/arch/arm/boot/dts/qcom/apq8096-v3-pmi8996-mdm9x55-i2s-mtp.dts
@@ -111,3 +111,153 @@
status = "okay";
};
};
+
+&soc {
+ sound {
+ status = "disabled";
+ };
+
+ sound-9335 {
+ status = "disabled";
+ };
+
+ slim_msm: slim@91c0000 {
+ status = "disabled";
+ };
+
+ clock_audio: audio_ext_clk {
+ compatible = "qcom,audio-ref-clk";
+ qcom,codec-mclk-clk-freq = <12288000>;
+ pinctrl-names = "sleep", "active";
+ pinctrl-0 = <&spkr_i2s_clk_sleep &ap_mclk_sleep
+ &mdm_mclk_sleep>;
+ pinctrl-1 = <&spkr_i2s_clk_active &ap_mclk_active
+ &mdm_mclk_sleep>;
+ };
+
+ i2c_7: i2c@75b5000 {
+ wcd9xxx_codec@d {
+ compatible = "qcom,tasha-i2c-pgd";
+ reg = <0x0d>;
+
+ interrupt-parent = <&wcd9xxx_intc>;
+ interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ 17 18 19 20 21 22 23 24 25 26 27 28 29
+ 30>;
+
+ qcom,cdc-reset-gpio = <&tlmm 64 0>;
+
+ clock-names = "wcd_clk";
+ clocks = <&clock_audio clk_audio_lpass_mclk2>;
+
+ cdc-vdd-buck-supply = <&pm8994_s4>;
+ qcom,cdc-vdd-buck-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-buck-current = <650000>;
+
+ cdc-buck-sido-supply = <&pm8994_s4>;
+ qcom,cdc-buck-sido-voltage = <1800000 1800000>;
+ qcom,cdc-buck-sido-current = <250000>;
+
+ cdc-vdd-tx-h-supply = <&pm8994_s4>;
+ qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-tx-h-current = <25000>;
+
+ cdc-vdd-rx-h-supply = <&pm8994_s4>;
+ qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-rx-h-current = <25000>;
+
+ cdc-vddpx-1-supply = <&pm8994_s4>;
+ qcom,cdc-vddpx-1-voltage = <1800000 1800000>;
+ qcom,cdc-vddpx-1-current = <10000>;
+
+ qcom,cdc-static-supplies = "cdc-vdd-buck",
+ "cdc-buck-sido",
+ "cdc-vdd-tx-h",
+ "cdc-vdd-rx-h",
+ "cdc-vddpx-1";
+
+ qcom,cdc-micbias1-mv = <1800>;
+ qcom,cdc-micbias2-mv = <1800>;
+ qcom,cdc-micbias3-mv = <1800>;
+ qcom,cdc-micbias4-mv = <1800>;
+
+ qcom,cdc-mclk-clk-rate = <12288000>;
+ qcom,cdc-dmic-sample-rate = <4800000>;
+ };
+ };
+
+ sound-9335-i2c {
+ compatible = "qcom,apq8096-asoc-snd-tasha-i2c";
+ qcom,model = "apq8096-tasha-i2c-snd-card";
+
+ qcom,audio-routing =
+ "AIF4 VI", "MCLK",
+ "RX_BIAS", "MCLK",
+ "MADINPUT", "MCLK",
+ "AMIC2", "MIC BIAS2",
+ "MIC BIAS2", "Headset Mic",
+ "AMIC3", "MIC BIAS2",
+ "MIC BIAS2", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2",
+ "MIC BIAS2", "ANCLeft Headset Mic",
+ "AMIC5", "MIC BIAS3",
+ "MIC BIAS3", "Handset Mic",
+ "AMIC6", "MIC BIAS4",
+ "MIC BIAS4", "Analog Mic6",
+ "DMIC0", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic0",
+ "DMIC1", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic1",
+ "DMIC2", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic2",
+ "DMIC3", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic3",
+ "DMIC4", "MIC BIAS4",
+ "MIC BIAS4", "Digital Mic4",
+ "DMIC5", "MIC BIAS4",
+ "MIC BIAS4", "Digital Mic5",
+ "SpkrLeft IN", "SPK1 OUT",
+ "SpkrRight IN", "SPK2 OUT";
+
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+ asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
+ <&loopback>, <&compress>, <&hostless>,
+ <&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>;
+ asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
+ "msm-pcm-dsp.2", "msm-voip-dsp",
+ "msm-pcm-voice", "msm-pcm-loopback",
+ "msm-compress-dsp", "msm-pcm-hostless",
+ "msm-pcm-afe", "msm-lsm-client",
+ "msm-pcm-routing", "msm-cpe-lsm",
+ "msm-compr-dsp";
+ asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>,
+ <&dai_mi2s>, <&dai_mi2s_quat>,
+ <&afe_pcm_rx>, <&afe_pcm_tx>,
+ <&afe_proxy_rx>, <&afe_proxy_tx>,
+ <&incall_record_rx>, <&incall_record_tx>,
+ <&incall_music_rx>, <&incall_music2_rx>;
+ asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2",
+ "msm-dai-q6-hdmi.8",
+ "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
+ "msm-dai-q6-dev.224", "msm-dai-q6-dev.225",
+ "msm-dai-q6-dev.241", "msm-dai-q6-dev.240",
+ "msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772",
+ "msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770";
+ qcom,tasha-mclk-clk-freq = <12288000>;
+ asoc-codec = <&stub_codec>;
+ asoc-codec-names = "msm-stub-codec.1";
+ };
+
+ qcom,msm-dai-mi2s {
+ dai_mi2s_quat: qcom,msm-dai-q6-mi2s-quat {
+ compatible = "qcom,msm-dai-q6-mi2s";
+ qcom,msm-dai-q6-mi2s-dev-id = <3>;
+ qcom,msm-mi2s-rx-lines = <2>;
+ qcom,msm-mi2s-tx-lines = <1>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&quat_mi2s_active &quat_mi2s_sd0_active>;
+ pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_sd0_sleep>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9607.dtsi b/arch/arm/boot/dts/qcom/mdm9607.dtsi
index c0fe6e033e13..d25bde94cc88 100644
--- a/arch/arm/boot/dts/qcom/mdm9607.dtsi
+++ b/arch/arm/boot/dts/qcom/mdm9607.dtsi
@@ -614,7 +614,7 @@
vdd-supply = <&mdm9607_l9>;
qcom,vdd-voltage-level = <0 1225000 1225000>;
qcom,hsic-tlmm-init-seq =
- <0x12008 0x5 0x12004 0x5 0x12000 0x1 0x8 0x400000>;
+ <0x12008 0x5 0x12004 0x5 0x12000 0x1>;
qcom,hsic-disable-on-boot;
clocks = <&clock_gcc clk_gcc_usb_hsic_ahb_clk>,
@@ -640,6 +640,36 @@
status = "disabled";
};
+ hsic_host: hsic_host@7c00000 {
+ compatible = "qcom,hsic-host";
+ reg = <0x7c00000 0x352>,
+ <0x1100000 0x1200c>;
+ interrupts = <0 141 0>, <0 142 0>;
+ interrupt-names = "core_irq", "async_irq";
+ hsic_vdd_dig-supply = <&mdm9607_l9>;
+ hsic,vdd-voltage-level = <0 1225000 1225000>;
+ qcom,hsic-tlmm-init-seq =
+ <0x12008 0x5 0x12004 0x5 0x12000 0x1>;
+ qcom,phy-susp-sof-workaround;
+ qcom,disable-internal-clk-gating;
+
+ clocks = <&clock_gcc clk_gcc_usb_hsic_ahb_clk>,
+ <&clock_gcc clk_gcc_usb_hsic_system_clk>,
+ <&clock_gcc clk_gcc_usb_hsic_clk>,
+ <&clock_gcc clk_gcc_usb_hsic_io_cal_clk>,
+ <&clock_gcc clk_gcc_usb_hsic_io_cal_sleep_clk>;
+ clock-names = "iface_clk", "core_clk", "phy_clk",
+ "cal_clk", "inactivity_clk";
+
+ qcom,msm-bus,name = "hsic";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <85 512 0 0>,
+ <85 512 60000 800000>;
+ status = "disabled";
+ };
+
qnand_1: nand@7980000 {
compatible = "qcom,msm-nand";
reg = <0x07980000 0x1000>,
diff --git a/arch/arm/boot/dts/qcom/mdmcalifornium-nand-dualwifi-mtp.dts b/arch/arm/boot/dts/qcom/mdmcalifornium-nand-dualwifi-mtp.dts
index 3482bd58970d..255a4ec37a3e 100644
--- a/arch/arm/boot/dts/qcom/mdmcalifornium-nand-dualwifi-mtp.dts
+++ b/arch/arm/boot/dts/qcom/mdmcalifornium-nand-dualwifi-mtp.dts
@@ -28,3 +28,34 @@
&cnss_sdio {
status = "ok";
};
+
+&sdhc_1 {
+ vdd-supply = <&sdc_vreg>;
+ vdd-io-supply = <&pmdcalifornium_l7>;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-current-level = <200 10000>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+ 200000000>;
+ qcom,bus-width = <4>;
+ qcom,core_3_0v_support;
+ qcom,nonremovable;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on
+ &sdc1_wlan_gpio_active>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off
+ &sdc1_wlan_gpio_sleep>;
+ #address-cells = <0>;
+ interrupt-parent = <&sdhc_1>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 123 0
+ 1 &intc 0 138 0
+ 2 &tlmm_pinmux 93 0x4>;
+ interrupt-names = "hc_irq", "pwr_irq", "sdiowakeup_irq";
+
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/qcom/mdmcalifornium-pinctrl.dtsi b/arch/arm/boot/dts/qcom/mdmcalifornium-pinctrl.dtsi
index 1afbd2f85f8c..80c57d7973d4 100644
--- a/arch/arm/boot/dts/qcom/mdmcalifornium-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/mdmcalifornium-pinctrl.dtsi
@@ -356,13 +356,13 @@
pcie0_wake_default: pcie0_wake_default {
mux {
- pins = "gpio65";
+ pins = "gpio61";
function = "gpio";
};
config {
- pins = "gpio65";
+ pins = "gpio61";
drive-strength = <2>;
- bias-pull-down;
+ bias-disable;
};
};
diff --git a/arch/arm/boot/dts/qcom/mdmcalifornium.dtsi b/arch/arm/boot/dts/qcom/mdmcalifornium.dtsi
index 5b06606e535a..72cdc2c3ae4a 100644
--- a/arch/arm/boot/dts/qcom/mdmcalifornium.dtsi
+++ b/arch/arm/boot/dts/qcom/mdmcalifornium.dtsi
@@ -361,7 +361,7 @@
&pcie0_wake_default>;
perst-gpio = <&tlmm_pinmux 60 0>;
- wake-gpio = <&tlmm_pinmux 65 0>;
+ wake-gpio = <&tlmm_pinmux 61 0>;
gdsc-vdd-supply = <&gdsc_pcie>;
vreg-1.8-supply = <&pmdcalifornium_l5>;
@@ -830,7 +830,6 @@
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
- qcom,not-wakeup; /* Needed until Full-boot-chain enabled */
};
tsens0: tsens@4a9000 {
diff --git a/arch/arm/boot/dts/qcom/msm-pmi8937.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8937.dtsi
index 49f07a3cd668..0c1f9ddf0efc 100644
--- a/arch/arm/boot/dts/qcom/msm-pmi8937.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmi8937.dtsi
@@ -32,6 +32,12 @@
qcom,secondary-pon-reset;
qcom,hard-reset-poweroff-type =
<PON_POWER_OFF_SHUTDOWN>;
+
+ pon_perph_reg: qcom,pon_perph_reg {
+ regulator-name = "pon_spare_reg";
+ qcom,pon-spare-reg-addr = <0x8c>;
+ qcom,pon-spare-reg-bit = <1>;
+ };
};
pmi8937_vadc: vadc@3100 {
@@ -419,6 +425,7 @@
qcom,en-phase-stag;
qcom,led-strings-list = [00 01];
qcom,en-ext-pfet-sc-pro;
+ qcom,cons-sync-write-delay-us = <1000>;
};
flash_led: qcom,leds@d300 {
@@ -495,6 +502,9 @@
qcom,duration = <1280>;
qcom,id = <2>;
qcom,current = <625>;
+ reg0 {
+ regulator-name = "pon_spare_reg";
+ };
};
};
@@ -504,6 +514,7 @@
interrupts = <0x3 0xc0 0x0>,
<0x3 0xc0 0x1>;
interrupt-names = "sc-irq", "play-irq";
+ vcc_pon-supply = <&pon_perph_reg>;
qcom,play-mode = "direct";
qcom,wave-play-rate-us = <5263>;
qcom,actuator-type = "lra";
@@ -521,7 +532,7 @@
qcom,wave-samp-rep-cnt = <1>;
qcom,lra-auto-res-mode="qwd";
qcom,lra-high-z="opt1";
- qcom,lra-res-cal-period = <0>;
+ qcom,lra-res-cal-period = <4>;
qcom,correct-lra-drive-freq;
qcom,misc-trim-error-rc19p2-clk-reg-present;
};
diff --git a/arch/arm/boot/dts/qcom/msm-pmi8950.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8950.dtsi
index 239740e191bd..b58bb840e745 100644
--- a/arch/arm/boot/dts/qcom/msm-pmi8950.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmi8950.dtsi
@@ -31,6 +31,12 @@
qcom,secondary-pon-reset;
qcom,hard-reset-poweroff-type =
<PON_POWER_OFF_SHUTDOWN>;
+
+ pon_perph_reg: qcom,pon_perph_reg {
+ regulator-name = "pon_spare_reg";
+ qcom,pon-spare-reg-addr = <0x8c>;
+ qcom,pon-spare-reg-bit = <1>;
+ };
};
pmi8950_vadc: vadc@3100 {
@@ -523,9 +529,9 @@
qcom,sync-dly-us = <800>;
qcom,fs-curr-ua = <20000>;
qcom,en-phase-stag;
- qcom,ibb-pwrup-dly = <8>;
qcom,led-strings-list = [00 01];
qcom,en-ext-pfet-sc-pro;
+ qcom,cons-sync-write-delay-us = <1000>;
};
flash_led: qcom,leds@d300 {
@@ -602,6 +608,9 @@
qcom,duration = <1280>;
qcom,id = <2>;
qcom,current = <625>;
+ reg0 {
+ regulator-name = "pon_spare_reg";
+ };
};
};
@@ -611,6 +620,7 @@
interrupts = <0x3 0xc0 0x0>,
<0x3 0xc0 0x1>;
interrupt-names = "sc-irq", "play-irq";
+ vcc_pon-supply = <&pon_perph_reg>;
qcom,play-mode = "direct";
qcom,wave-play-rate-us = <5263>;
qcom,actuator-type = "erm";
diff --git a/arch/arm/boot/dts/qcom/msm8917-pmi8937-qrd-sku5.dts b/arch/arm/boot/dts/qcom/msm8917-pmi8937-qrd-sku5.dts
index 3ff351b94497..d71efe085bba 100644
--- a/arch/arm/boot/dts/qcom/msm8917-pmi8937-qrd-sku5.dts
+++ b/arch/arm/boot/dts/qcom/msm8917-pmi8937-qrd-sku5.dts
@@ -24,5 +24,5 @@
};
&int_codec {
- qcom,model = "msm8952-sku2-snd-card";
+ qcom,model = "msm8917-sku5-snd-card";
};
diff --git a/arch/arm/boot/dts/qcom/msm8917-qgp-tmo.dtsi b/arch/arm/boot/dts/qcom/msm8917-qgp-tmo.dtsi
index f02780542b17..48b5e4d71665 100644
--- a/arch/arm/boot/dts/qcom/msm8917-qgp-tmo.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8917-qgp-tmo.dtsi
@@ -21,6 +21,39 @@
};
&soc {
+
+ i2c@78b7000 {
+ status = "ok";
+ goodix@5d{
+ compatible = "goodix,gt9xx";
+ reg = <0x5d>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <65 0x02>;
+ avdd-supply = <&pm8917_l17>;
+ vdd-supply = <&pm8917_l17>;
+ vcc_i2c-supply = <&pm8917_l6>;
+ reset-gpios = <&tlmm 64 0x00>;
+ interrupt-gpios = <&tlmm 65 0x2008>;
+ goodix,panel-coords = <0 0 720 1200>;
+ goodix,display-coords = <0 0 720 1080>;
+ goodix,button-map= <139 172 158>;
+ goodix,product-id = "5668";
+ goodix,fw_name = "gtp_fw.bin";
+ goodix,have-touch-key;
+ goodix,driver-send-cfg;
+ };
+ };
+
+ gpio_keys {
+ vol_down {
+ label = "volume_down";
+ gpios = <&tlmm 128 0x1>;
+ linux,input-type = <1>;
+ linux,code = <114>;
+ debounce-interval = <15>;
+ };
+ };
+
led_flash0: qcom,camera-flash {
};
};
@@ -73,3 +106,7 @@
qcom,bad-battery-detection-enable;
qcom,hold-soc-while-full;
};
+
+&int_codec {
+ qcom,model = "msm8917-tmo-snd-card";
+};
diff --git a/arch/arm/boot/dts/qcom/msm8917-regulator.dtsi b/arch/arm/boot/dts/qcom/msm8917-regulator.dtsi
index 0dffb6d85459..27f4c2e09676 100644
--- a/arch/arm/boot/dts/qcom/msm8917-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8917-regulator.dtsi
@@ -434,14 +434,18 @@
qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>;
qcom,cpr-scaled-init-voltage-as-ceiling;
qcom,cpr-fuse-revision = <69 39 3 0>;
+ qcom,pvs-version-fuse-sel = <37 40 3 0>; /* foundry */
qcom,cpr-fuse-version-map =
- <(-1) (-1) 1 (-1) (-1) (-1)>,
+ <(-1) 0 1 (-1) (-1) (-1)>,
+ <(-1) 5 1 (-1) (-1) (-1)>,
<(-1) (-1) (-1) (-1) (-1) (-1)>;
qcom,cpr-quotient-adjustment =
<50 40 100>,
+ <0 0 40>,
<0 0 0>;
qcom,cpr-init-voltage-adjustment =
<30000 5000 35000>,
+ <0 0 20000>,
<0 0 0>;
qcom,cpr-enable;
};
diff --git a/arch/arm/boot/dts/qcom/msm8917.dtsi b/arch/arm/boot/dts/qcom/msm8917.dtsi
index bb852830bb3e..809ce158d64b 100644
--- a/arch/arm/boot/dts/qcom/msm8917.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8917.dtsi
@@ -245,6 +245,9 @@
qcom,sensors = <10>;
qcom,slope = <3200 3200 3200 3200 3200 3200 3200 3200 3200
3200>;
+ qcom,temp1-offset = <1 (-6) (-6) (-2) (-7) (-5) (-2) (-8) (-10)
+ (-6)>;
+ qcom,temp2-offset = <(-3) 1 (-2) 7 (-9) (-18) (-7) (-2) 1 16>;
qcom,valid-status-check;
};
@@ -1261,9 +1264,9 @@
qcom,ce-opp-freq = <100000000>;
};
- qcom_seecom: qseecom@85e00000 {
+ qcom_seecom: qseecom@85b00000 {
compatible = "qcom,qseecom";
- reg = <0x85e00000 0x500000>;
+ reg = <0x85b00000 0x800000>;
reg-names = "secapp-region";
qcom,hlos-num-ce-hw-instances = <1>;
qcom,hlos-ce-hw-instance = <0>;
diff --git a/arch/arm/boot/dts/qcom/msm8937-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8937-cdp.dtsi
index 75ab92f5bacb..458b5d6d15e7 100644
--- a/arch/arm/boot/dts/qcom/msm8937-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8937-cdp.dtsi
@@ -130,6 +130,11 @@
&pmi_haptic{
qcom,wave-play-rate-us = <4165>;
qcom,actuator-type = "lra";
+ qcom,lra-auto-res-mode="qwd";
+ qcom,lra-high-z="opt1";
+ qcom,lra-res-cal-period = <4>;
+ qcom,correct-lra-drive-freq;
+ qcom,misc-trim-error-rc19p2-clk-reg-present;
};
&sdhc_1 {
diff --git a/arch/arm/boot/dts/qcom/msm8937-coresight.dtsi b/arch/arm/boot/dts/qcom/msm8937-coresight.dtsi
index 6a8a8bf09cc5..d82cc9557b52 100644
--- a/arch/arm/boot/dts/qcom/msm8937-coresight.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8937-coresight.dtsi
@@ -887,7 +887,7 @@
qcom,inst-id = <5>;
};
- modem_etm0 {
+ modem_etm0: modem_etm0 {
compatible = "qcom,coresight-remote-etm";
coresight-id = <51>;
diff --git a/arch/arm/boot/dts/qcom/msm8937-gpu.dtsi b/arch/arm/boot/dts/qcom/msm8937-gpu.dtsi
index cabb82e06a25..90b7a91e664b 100644
--- a/arch/arm/boot/dts/qcom/msm8937-gpu.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8937-gpu.dtsi
@@ -36,15 +36,17 @@
< 4248 >, /* 6. DDR:556.80 MHz BIMC: 278.40 MHz */
< 5346 >, /* 7. DDR:662.40 MHz BIMC: 331.20 MHz */
< 5712 >, /* 8. DDR:748.80 MHz BIMC: 374.40 MHz */
- < 6152 >; /* 9. DDR:806.40 MHz BIMC: 403.20 MHz */
+ < 6152 >, /* 9. DDR:806.40 MHz BIMC: 403.20 MHz */
+ < 7031 >; /* 10. DDR:921.60 MHz BIMC: 460.80 MHz */
};
msm_gpu: qcom,kgsl-3d0@1c00000 {
label = "kgsl-3d0";
compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d";
status = "ok";
- reg = <0x1c00000 0x40000>;
- reg-names = "kgsl_3d0_reg_memory";
+ reg = <0x1c00000 0x40000
+ 0xa0000 0x6fff>;
+ reg-names = "kgsl_3d0_reg_memory", "qfprom_memory";
interrupts = <0 33 0>;
interrupt-names = "kgsl_3d0_irq";
qcom,id = <0>;
@@ -57,6 +59,8 @@
qcom,highest-bank-bit = <14>;
+ qcom,snapshot-size = <1048576>; //bytes
+
clocks = <&clock_gcc clk_gcc_oxili_gfx3d_clk>,
<&clock_gcc clk_gcc_oxili_ahb_clk>,
<&clock_gcc clk_gcc_bimc_gfx_clk>,
@@ -74,7 +78,7 @@
qcom,bus-control;
qcom,bus-width = <16>;
qcom,msm-bus,name = "grp3d";
- qcom,msm-bus,num-cases = <10>;
+ qcom,msm-bus,num-cases = <11>;
qcom,msm-bus,num-paths = <1>;
qcom,msm-bus,vectors-KBps =
<26 512 0 0>, /* off */
@@ -86,7 +90,8 @@
<26 512 0 4454400>, /* 6. 556.80 MHz */
<26 512 0 5299200>, /* 7. 662.40 MHz */
<26 512 0 5990400>, /* 8. 748.80 MHz */
- <26 512 0 6451200>; /* 9. 806.40 MHz */
+ <26 512 0 6451200>, /* 9. 806.40 MHz */
+ <26 512 0 7372800>; /* 10. 921.60 MHz */
/* GDSC regulator names */
regulator-names = "vddcx", "vdd";
diff --git a/arch/arm/boot/dts/qcom/msm8937-mdss.dtsi b/arch/arm/boot/dts/qcom/msm8937-mdss.dtsi
index 090f88a20c6c..4e341a1178af 100644
--- a/arch/arm/boot/dts/qcom/msm8937-mdss.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8937-mdss.dtsi
@@ -172,6 +172,16 @@
<1 590 0 320000>;
};
+ qcom,mdss-hw-rt-bus {
+ /* Bus Scale Settings */
+ qcom,msm-bus,name = "mdss_hw_rt";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <22 512 0 0>,
+ <22 512 0 1000>;
+ };
+
smmu_mdp_unsec: qcom,smmu_mdp_unsec_cb {
compatible = "qcom,smmu_mdp_unsec";
};
diff --git a/arch/arm/boot/dts/qcom/msm8937-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8937-mtp.dtsi
index b8c21d885b55..4ddd3a3d336c 100644
--- a/arch/arm/boot/dts/qcom/msm8937-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8937-mtp.dtsi
@@ -78,6 +78,11 @@
&pmi_haptic{
qcom,wave-play-rate-us = <4165>;
qcom,actuator-type = "lra";
+ qcom,lra-auto-res-mode="qwd";
+ qcom,lra-high-z="opt1";
+ qcom,lra-res-cal-period = <4>;
+ qcom,correct-lra-drive-freq;
+ qcom,misc-trim-error-rc19p2-clk-reg-present;
};
&spi_3 { /* BLSP1 QUP3 */
diff --git a/arch/arm/boot/dts/qcom/msm8937-regulator.dtsi b/arch/arm/boot/dts/qcom/msm8937-regulator.dtsi
index 9f0b79d5b085..ad65f6354f5d 100644
--- a/arch/arm/boot/dts/qcom/msm8937-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8937-regulator.dtsi
@@ -356,7 +356,7 @@
interrupts = <0 15 0>;
regulator-name = "apc_corner";
regulator-min-microvolt = <1>;
- regulator-max-microvolt = <6>;
+ regulator-max-microvolt = <7>;
qcom,cpr-fuse-corners = <3>;
qcom,cpr-voltage-ceiling = <1155000 1225000 1350000>;
@@ -393,17 +393,19 @@
<70 54 7 0>;
qcom,cpr-fuse-quot-offset-scale = <5 5 5>;
qcom,cpr-init-voltage-step = <10000>;
- qcom,cpr-corner-map = <1 2 3 3 3 3>;
+ qcom,cpr-corner-map = <1 2 3 3 3 3 3>;
qcom,cpr-corner-frequency-map =
<1 960000000>,
<2 1094400000>,
<3 1209600000>,
<4 1248000000>,
<5 1344000000>,
- <6 1401000000>;
+ <6 1401000000>,
+ <7 1497600000>;
qcom,speed-bin-fuse-sel = <37 34 3 0>;
qcom,cpr-speed-bin-max-corners =
<0 0 1 2 6>,
+ <1 0 1 2 7>,
<2 0 1 2 3>;
qcom,cpr-fuse-revision = <69 39 3 0>;
qcom,cpr-quot-adjust-scaling-factor-max = <0 1400 1400>;
diff --git a/arch/arm/boot/dts/qcom/msm8937.dtsi b/arch/arm/boot/dts/qcom/msm8937.dtsi
index d7d2958790bd..4660fb59ccdb 100644
--- a/arch/arm/boot/dts/qcom/msm8937.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8937.dtsi
@@ -692,12 +692,33 @@
< 1344000000 5>,
< 1401000000 6>;
-
qcom,speed0-bin-v0-cci =
< 0 0>,
< 400000000 1>,
< 533333333 3>;
+ qcom,speed1-bin-v0-c0 =
+ < 0 0>,
+ < 768000000 1>,
+ < 902400000 2>,
+ < 998400000 4>,
+ < 1094400000 6>,
+ < 1209600000 7>;
+
+ qcom,speed1-bin-v0-c1 =
+ < 0 0>,
+ < 960000000 1>,
+ < 1094400000 2>,
+ < 1248000000 4>,
+ < 1344000000 5>,
+ < 1401000000 6>,
+ < 1497600000 7>;
+
+ qcom,speed1-bin-v0-cci =
+ < 0 0>,
+ < 400000000 1>,
+ < 533333333 3>;
+
qcom,speed2-bin-v0-c0 =
< 0 0>,
< 768000000 1>,
@@ -740,13 +761,15 @@
< 1209600 >,
< 1248000 >,
< 1344000 >,
- < 1401000 >;
+ < 1401000 >,
+ < 1497600 >;
qcom,cpufreq-table-4 =
< 768000 >,
< 902400 >,
< 998400 >,
- < 1094400 >;
+ < 1094400 >,
+ < 1209600 >;
};
cci_cache: qcom,cci {
@@ -812,12 +835,12 @@
< 1094400 5053 >, /* NOM */
< 1248000 5712 >, /* NOM+ */
< 1344000 7031 >,
- < 1401000 7031 >; /* TURBO */
+ < 1497600 7031 >; /* TURBO */
cpu-to-dev-map-4 =
< 806400 2929 >, /* SVS */
< 902400 5053 >, /* NOM */
< 998400 6152 >, /* NOM+ */
- < 1094400 7031 >; /* TURBO */
+ < 1209600 7031 >; /* TURBO */
};
cci-cpufreq {
@@ -827,22 +850,22 @@
< 1094400 400000 >, /* NOM */
< 1248000 533333 >, /* NOM+ */
< 1344000 533333 >,
- < 1401000 533333 >; /* TURBO */
+ < 1497600 533333 >; /* TURBO */
cpu-to-dev-map-4 =
< 806400 400000 >, /* SVS */
< 902400 400000 >, /* NOM */
< 998400 533333 >, /* NOM+ */
- < 1094400 533333 >; /* TURBO */
+ < 1209600 533333 >; /* TURBO */
};
mincpubw-cpufreq {
target-dev = <&mincpubw>;
cpu-to-dev-map-0 =
< 1094400 2929 >,
- < 1401000 4248 >;
+ < 1497600 4248 >;
cpu-to-dev-map-4 =
< 998400 2929 >,
- < 1094400 4248 >;
+ < 1209600 4248 >;
};
};
@@ -1568,7 +1591,7 @@
};
};
- qcom,bam_dmux@4044000 {
+ bam_dmux: qcom,bam_dmux@4044000 {
compatible = "qcom,bam_dmux";
reg = <0x4044000 0x19000>;
interrupts = <0 162 1>;
@@ -1988,3 +2011,151 @@
clocks = <&clock_gcc clk_gcc_oxili_gfx3d_clk>;
status = "okay";
};
+
+/* GPU overrides */
+&msm_gpu {
+
+ qcom,gpu-speed-bin = <0x6018 0x80000000 31>;
+
+ qcom,gpu-pwrlevel-bins {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible="qcom,gpu-pwrlevel-bins";
+
+ qcom,gpu-pwrlevels-0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <0>;
+
+ qcom,initial-pwrlevel = <2>;
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <450000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <9>;
+ };
+
+ /* NOM+ */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <400000000>;
+ qcom,bus-freq = <7>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <9>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <375000000>;
+ qcom,bus-freq = <6>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <8>;
+ };
+
+ /* SVS+ */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <300000000>;
+ qcom,bus-freq = <5>;
+ qcom,bus-min = <4>;
+ qcom,bus-max = <7>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <216000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <1>;
+ qcom,bus-max = <4>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+
+ qcom,gpu-pwrlevels-1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <1>;
+
+ qcom,initial-pwrlevel = <3>;
+
+ /* Super TURBO */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <475000000>;
+ qcom,bus-freq = <10>;
+ qcom,bus-min = <10>;
+ qcom,bus-max = <10>;
+ };
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <45000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <10>;
+ };
+
+ /* NOM+ */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <400000000>;
+ qcom,bus-freq = <7>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <9>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <375000000>;
+ qcom,bus-freq = <6>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <8>;
+ };
+
+ /* SVS+ */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <300000000>;
+ qcom,bus-freq = <5>;
+ qcom,bus-min = <4>;
+ qcom,bus-max = <7>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <216000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <1>;
+ qcom,bus-max = <4>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@6 {
+ reg = <6>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm8940-pmi8950-ext-codec-cdp.dts b/arch/arm/boot/dts/qcom/msm8940-pmi8950-ext-codec-cdp.dts
new file mode 100644
index 000000000000..1089dc9259b2
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msm8940-pmi8950-ext-codec-cdp.dts
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016, 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 "msm8940.dtsi"
+#include "msm8940-pmi8950-cdp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM8940 External Audio Codec CDP";
+ compatible = "qcom,msm8940-cdp", "qcom,msm8940", "qcom,cdp";
+ qcom,board-id= <1 1>;
+ qcom,pmic-id = <0x10019 0x010011 0x0 0x0>;
+};
+
+&pm8937_gpios {
+ gpio@c000 {
+ status = "ok";
+ qcom,mode = <1>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <0>;
+ qcom,src-sel = <2>;
+ qcom,master-en = <1>;
+ qcom,out-strength = <2>;
+ };
+
+ gpio@c600 {
+ status = "ok";
+ qcom,mode = <1>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <0>;
+ qcom,src-sel = <0>;
+ qcom,master-en = <1>;
+ qcom,out-strength = <2>;
+ };
+};
+
+&slim_msm {
+ status = "okay";
+};
+
+&dai_slim {
+ status = "okay";
+};
+
+&wcd9xxx_intc {
+ status = "okay";
+};
+
+&clock_audio {
+ status = "okay";
+};
+
+&wcd9335 {
+ status = "okay";
+};
+
+&ext_codec {
+ status = "okay";
+};
+
+&wcd_rst_gpio {
+ status = "okay";
+};
+
+&int_codec {
+ status = "disabled";
+};
+
+&pm8937_cajon_dig {
+ status = "disabled";
+};
+
+&pm8937_cajon_analog {
+ status = "disabled";
+};
+
+&wsa881x_i2c_e {
+ status = "disabled";
+};
+
+&wsa881x_i2c_44 {
+ status = "disabled";
+};
+
+&wsa881x_i2c_f {
+ status = "disabled";
+};
+
+&wsa881x_i2c_45 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/qcom/msm8940-pmi8950-qrd-sku6.dts b/arch/arm/boot/dts/qcom/msm8940-pmi8950-qrd-sku6.dts
index b24c38c0a8ef..aa0960d8726f 100644
--- a/arch/arm/boot/dts/qcom/msm8940-pmi8950-qrd-sku6.dts
+++ b/arch/arm/boot/dts/qcom/msm8940-pmi8950-qrd-sku6.dts
@@ -51,7 +51,7 @@
&soc {
sound {
- qcom,model = "msm8952-sku1-snd-card";
+ qcom,model = "msm8940-sku6-snd-card";
qcom,msm-hs-micbias-type = "internal";
qcom,audio-routing =
"RX_BIAS", "MCLK",
diff --git a/arch/arm/boot/dts/qcom/msm8940.dtsi b/arch/arm/boot/dts/qcom/msm8940.dtsi
index a5265c3ae977..2ed34b351546 100644
--- a/arch/arm/boot/dts/qcom/msm8940.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8940.dtsi
@@ -23,6 +23,58 @@
};
+&usb_otg {
+ qcom,usbbam@78c4000 {
+ qcom,enable-hsusb-bam-on-boot;
+
+ /delete-node/ qcom,pipe0;
+ qcom,pipe0 {
+ label = "hsusb-ipa-out-0";
+ qcom,usb-bam-mem-type = <1>;
+ qcom,dir = <0>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <1>;
+ qcom,src-bam-pipe-index = <1>;
+ qcom,data-fifo-size = <0x8000>;
+ qcom,descriptor-fifo-size = <0x2000>;
+ };
+ qcom,pipe1 {
+ label = "hsusb-ipa-in-0";
+ qcom,usb-bam-mem-type = <1>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <1>;
+ qcom,dst-bam-pipe-index = <0>;
+ qcom,data-fifo-size = <0x8000>;
+ qcom,descriptor-fifo-size = <0x2000>;
+ };
+ qcom,pipe2 {
+ label = "hsusb-qdss-in-0";
+ qcom,usb-bam-mem-type = <2>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <0>;
+ qcom,peer-bam-physical-address = <0x6044000>;
+ qcom,src-bam-pipe-index = <0>;
+ qcom,dst-bam-pipe-index = <2>;
+ qcom,data-fifo-offset = <0x0>;
+ qcom,data-fifo-size = <0xe00>;
+ qcom,descriptor-fifo-offset = <0xe00>;
+ qcom,descriptor-fifo-size = <0x200>;
+ };
+ qcom,pipe3 {
+ label = "hsusb-dpl-ipa-in-1";
+ qcom,usb-bam-mem-type = <1>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <1>;
+ qcom,peer-bam = <1>;
+ qcom,dst-bam-pipe-index = <3>;
+ qcom,data-fifo-size = <0x8000>;
+ qcom,descriptor-fifo-size = <0x2000>;
+ };
+ };
+};
+
&ad_hoc_bus {
mas_ipa: mas-ipa {
cell-id = <MSM_BUS_MASTER_IPA>;
@@ -39,3 +91,245 @@
qcom,mas-rpm-id = <ICBID_MASTER_IPA>;
};
};
+
+&clock_gcc {
+ compatible = "qcom,gcc-8940";
+};
+
+&clock_debug {
+ compatible = "qcom,cc-debug-8940";
+};
+
+&clock_gcc_mdss {
+ compatible = "qcom,gcc-mdss-8940";
+};
+
+&bam_dmux {
+ status = "disabled";
+};
+
+&soc {
+ ipa_hw: qcom,ipa@07900000 {
+ compatible = "qcom,ipa";
+ reg = <0x07900000 0x4effc>, <0x07904000 0x26934>;
+ reg-names = "ipa-base", "bam-base";
+ interrupts = <0 228 0>,
+ <0 230 0>;
+ interrupt-names = "ipa-irq", "bam-irq";
+ qcom,ipa-hw-ver = <6>; /* IPA core version = IPAv2.6L */
+ qcom,ipa-hw-mode = <0>; /* IPA hw type = Normal */
+ clock-names = "core_clk";
+ clocks = <&clock_gcc clk_ipa_clk>;
+ qcom,ee = <0>;
+ qcom,use-ipa-tethering-bridge;
+ qcom,modem-cfg-emb-pipe-flt;
+ qcom,msm-bus,name = "ipa";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <90 512 0 0>, /* No BIMC vote (ab=0 Mbps, ib=0 Mbps ~ 0MHZ) */
+ <90 512 100000 800000>, /* SVS (ab=100, ib=800 ~ 50MHz) */
+ <90 512 100000 1200000>; /* PERF (ab=100, ib=1200 ~ 75MHz) */
+ qcom,bus-vector-names = "MIN", "SVS", "PERF";
+ };
+
+ qcom,rmnet-ipa {
+ compatible = "qcom,rmnet-ipa";
+ qcom,rmnet-ipa-ssr;
+ qcom,ipa-loaduC;
+ qcom,ipa-advertise-sg-support;
+ };
+
+ /* remove 8937 MEM ACC node */
+ /delete-node/ regulator@01946004;
+
+ mem_acc_vreg_corner: regulator@01946004 {
+ compatible = "qcom,mem-acc-regulator";
+ regulator-name = "mem_acc_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <3>;
+
+ qcom,acc-reg-addr-list =
+ <0x01942138 0x01942130 0x01942120
+ 0x01942124 0x01942128>;
+
+ qcom,acc-init-reg-config = <1 0xfff>;
+
+ qcom,num-acc-corners = <3>;
+ qcom,boot-acc-corner = <2>;
+ qcom,corner1-reg-config =
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 2 0x555555 >, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x0>, < 4 0x0>,
+ < 5 0x0>;
+
+ qcom,corner2-reg-config =
+ /* NOM => SVS+ */
+ < 2 0x555555>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 2 0x555555>, < 3 0x0>, < 4 0x0>,
+ < 5 0x0>;
+
+ qcom,corner3-reg-config =
+ /* TURBO/NOM+ => SVS+ */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* TURBO/NOM+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>;
+ };
+};
+
+&apc_vreg_corner {
+ /delete-property/ qcom,cpr-fuse-version-map;
+ /delete-property/ qcom,cpr-quotient-adjustment;
+ /delete-property/ qcom,cpr-init-voltage-adjustment;
+ /delete-property/ qcom,cpr-enable;
+};
+
+/* GPU overrides */
+&msm_gpu {
+
+ /delete-node/qcom,gpu-pwrlevels;
+
+ /* Power levels */
+ qcom,gpu-pwrlevels {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,gpu-pwrlevels";
+
+ /* SUPER TURBO */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <450000000>;
+ qcom,bus-freq = <10>;
+ qcom,bus-min = <10>;
+ qcom,bus-max = <10>;
+ };
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <450000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <10>;
+ };
+
+ /* NOM+ */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <400000000>;
+ qcom,bus-freq = <7>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <9>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <375000000>;
+ qcom,bus-freq = <6>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <8>;
+ };
+
+ /* SVS+ */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <300000000>;
+ qcom,bus-freq = <5>;
+ qcom,bus-min = <4>;
+ qcom,bus-max = <7>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <216000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <1>;
+ qcom,bus-max = <4>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@6 {
+ reg = <6>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+};
+
+&mdss_mdp {
+ qcom,vbif-settings = <0x0d0 0x00000020>;
+};
+
+&modem_mem {
+ reg = <0x0 0x86800000 0x0 0x6a00000>;
+};
+
+&reloc_mem {
+ reg = <0x0 0x8d200000 0x0 0x1800000>;
+};
+
+&funnel_apss {
+ coresight-child-ports = <3>;
+};
+
+/* MSS_SCL */
+&modem_etm0 {
+ coresight-child-ports = <2>;
+ qcom,inst-id = <11>;
+};
+
+&soc {
+ cti_modem_cpu1: cti@6128000{
+ compatible = "arm,coresight-cti";
+ reg = <0x6128000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <59>;
+ coresight-name = "coresight-cti-modem-cpu1";
+ coresight-nr-inports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ /* MSS_VEC */
+ modem_etm1 {
+ compatible = "qcom,coresight-remote-etm";
+
+ coresight-id = <60>;
+ coresight-name = "coresight-modem-etm1";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_right>;
+ coresight-child-ports = <1>;
+
+ qcom,inst-id = <2>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm8953-gpu.dtsi b/arch/arm/boot/dts/qcom/msm8953-gpu.dtsi
index a6cf0030cb53..99881a6f98d5 100644
--- a/arch/arm/boot/dts/qcom/msm8953-gpu.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8953-gpu.dtsi
@@ -75,6 +75,8 @@
qcom,highest-bank-bit = <14>;
+ qcom,snapshot-size = <1048576>; //bytes
+
clocks = <&clock_gcc_gfx clk_gcc_oxili_gfx3d_clk>,
<&clock_gcc_gfx clk_gcc_oxili_ahb_clk>,
<&clock_gcc_gfx clk_gcc_bimc_gfx_clk>,
@@ -127,6 +129,15 @@
coresight-child-list = <&funnel_mm>;
coresight-child-ports = <6>;
+ /* Enable context aware freq. scaling */
+ qcom,enable-ca-jump;
+
+ /* Context aware jump busy penalty in us */
+ qcom,ca-busy-penalty = <12000>;
+
+ /* Context aware jump target power level */
+ qcom,ca-target-pwrlevel = <3>;
+
/* Power levels */
qcom,gpu-pwrlevels {
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom/msm8953-mdss.dtsi b/arch/arm/boot/dts/qcom/msm8953-mdss.dtsi
index a7542f648d7d..619809a72965 100644
--- a/arch/arm/boot/dts/qcom/msm8953-mdss.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8953-mdss.dtsi
@@ -173,6 +173,16 @@
<1 590 0 320000>;
};
+ qcom,mdss-hw-rt-bus {
+ /* Bus Scale Settings */
+ qcom,msm-bus,name = "mdss_hw_rt";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <22 512 0 0>,
+ <22 512 0 1000>;
+ };
+
smmu_mdp_unsec: qcom,smmu_mdp_unsec_cb {
compatible = "qcom,smmu_mdp_unsec";
};
diff --git a/arch/arm/boot/dts/qcom/msm8953-regulator.dtsi b/arch/arm/boot/dts/qcom/msm8953-regulator.dtsi
index d2f47d0c180c..e0263f1c8248 100644
--- a/arch/arm/boot/dts/qcom/msm8953-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8953-regulator.dtsi
@@ -371,6 +371,13 @@
qcom,cpr-enable;
qcom,cpr-hw-closed-loop;
+ qcom,cpr-panic-reg-addr-list =
+ <0xb1d2c18 0xb1d2900 0x0b1112b0 0xb018798>;
+ qcom,cpr-panic-reg-name-list =
+ "CCI_SAW4_PMIC_STS", "CCI_SAW4_VCTL",
+ "APCS_ALIAS0_APM_CTLER_STATUS",
+ "APCS0_CPR_CORE_ADJ_MODE_REG";
+
thread@0 {
qcom,cpr-thread-id = <0>;
qcom,cpr-consecutive-up = <0>;
@@ -636,9 +643,9 @@
qcom,cpr-closed-loop-voltage-fuse-adjustment =
/* Speed bin 0; CPR rev 0..7 */
< 0 0 0 0>,
- < 25000 0 20000 50000>,
- < 25000 0 20000 50000>,
- < 25000 0 20000 50000>,
+ < 10000 (-15000) 0 25000>,
+ < 10000 (-15000) 0 25000>,
+ < 10000 (-15000) 0 25000>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>,
@@ -656,9 +663,9 @@
/* Speed bin 2; CPR rev 0..7 */
< 0 0 0 0>,
- < 25000 0 20000 50000>,
- < 25000 0 20000 50000>,
- < 25000 0 20000 50000>,
+ < 10000 (-15000) 0 25000>,
+ < 10000 (-15000) 0 25000>,
+ < 10000 (-15000) 0 25000>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>,
@@ -706,9 +713,9 @@
/* Speed bin 7; CPR rev 0..7 */
< 0 0 0 0>,
- < 25000 0 20000 50000>,
- < 25000 0 20000 50000>,
- < 25000 0 20000 50000>,
+ < 10000 (-15000) 0 25000>,
+ < 10000 (-15000) 0 25000>,
+ < 10000 (-15000) 0 25000>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>,
diff --git a/arch/arm/boot/dts/qcom/msm8996-camera.dtsi b/arch/arm/boot/dts/qcom/msm8996-camera.dtsi
index 43ccbb123c12..e24d4b3c2c07 100644
--- a/arch/arm/boot/dts/qcom/msm8996-camera.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-camera.dtsi
@@ -692,9 +692,9 @@
"smmu_cpp_ahb_clk";
qcom,clock-rates =
<0 0 0 400000000 400000000 0 0 0 0 0 0 0>,
- <0 0 0 400000000 400000000 0 0 0 0 0 0 0>,
+ <0 0 0 100000000 100000000 0 0 0 0 0 0 0>,
<0 0 0 200000000 200000000 0 0 0 0 0 0 0>,
- <0 0 0 100000000 100000000 0 0 0 0 0 0 0>;
+ <0 0 0 400000000 400000000 0 0 0 0 0 0 0>;
qcom,msm-bus,name = "msm_camera_fd";
qcom,msm-bus,num-cases = <4>;
qcom,msm-bus,num-paths = <1>;
diff --git a/arch/arm/boot/dts/qcom/msm8996-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8996-cdp.dtsi
index 23a65ccd7fd6..57f5adc54610 100644
--- a/arch/arm/boot/dts/qcom/msm8996-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-cdp.dtsi
@@ -410,6 +410,7 @@
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,panel-roi-alignment = <720 128 720 64 720 64>;
+ qcom,panel-allow-phy-poweroff;
};
&dsi_nt35950_4k_dsc_cmd {
@@ -448,6 +449,7 @@
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,panel-allow-phy-poweroff;
};
&dsi_dual_sharp_1080_120hz_cmd {
diff --git a/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi b/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi
index 81f4fa8dda73..25e0d99987db 100644
--- a/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi
@@ -77,6 +77,8 @@
qcom,highest-bank-bit = <15>;
+ qcom,snapshot-size = <1048576>; //bytes
+
/* Trace bus */
coresight-id = <300>;
coresight-name = "coresight-gfx";
diff --git a/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi
index c34efa60b766..9517f2378a78 100644
--- a/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi
@@ -400,6 +400,7 @@
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,panel-roi-alignment = <720 128 720 64 720 64>;
+ qcom,panel-allow-phy-poweroff;
};
&dsi_nt35950_4k_dsc_cmd {
@@ -438,6 +439,7 @@
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,panel-allow-phy-poweroff;
};
&dsi_dual_sharp_1080_120hz_cmd {
diff --git a/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi
index 0b7be6a056f3..1676090dd4ff 100644
--- a/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi
@@ -1533,24 +1533,24 @@
tert_mi2s {
tert_mi2s_sleep: tert_mi2s_sleep {
mux {
- pins = "gpio75", "gpio76";
+ pins = "gpio75", "gpio76", "gpio78";
function = "ter_mi2s";
};
config {
- pins = "gpio75", "gpio76";
+ pins = "gpio75", "gpio76", "gpio78";
drive-strength = <2>; /* 2 mA */
bias-pull-down; /* PULL DOWN */
};
};
tert_mi2s_active: tert_mi2s_active {
mux {
- pins = "gpio75", "gpio76";
+ pins = "gpio75", "gpio76", "gpio78";
function = "ter_mi2s";
};
config {
- pins = "gpio75", "gpio76";
+ pins = "gpio75", "gpio76", "gpio78";
drive-strength = <8>; /* 8 mA */
bias-disable; /* NO PULL */
output-high;
@@ -1588,24 +1588,24 @@
quat_mi2s {
quat_mi2s_sleep: quat_mi2s_sleep {
mux {
- pins = "gpio58", "gpio59";
+ pins = "gpio58", "gpio59", "gpio61";
function = "qua_mi2s";
};
config {
- pins = "gpio58", "gpio59";
+ pins = "gpio58", "gpio59", "gpio61";
drive-strength = <2>; /* 2 mA */
bias-pull-down; /* PULL DOWN */
};
};
quat_mi2s_active: quat_mi2s_active {
mux {
- pins = "gpio58", "gpio59";
+ pins = "gpio58", "gpio59", "gpio61";
function = "qua_mi2s";
};
config {
- pins = "gpio58", "gpio59";
+ pins = "gpio58", "gpio59", "gpio61";
drive-strength = <8>; /* 8 mA */
bias-disable; /* NO PULL */
output-high;
@@ -1804,6 +1804,64 @@
};
};
+ ap_mclk_en {
+ ap_mclk_active: ap_mclk_active {
+ mux {
+ pins = "gpio133";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio133";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+ };
+ ap_mclk_sleep: ap_mclk_sleep {
+ mux {
+ pins = "gpio133";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio133";
+ drive-strength = <2>;
+ bias-pull-down;
+ output-low;
+ };
+ };
+ };
+
+ mdm_mclk_en {
+ mdm_mclk_active: mdm_mclk_active {
+ mux {
+ pins = "gpio134";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio134";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+ };
+ mdm_mclk_sleep: mdm_mclk_sleep {
+ mux {
+ pins = "gpio134";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio134";
+ drive-strength = <2>;
+ bias-pull-down;
+ output-low;
+ };
+ };
+ };
+
cci0_active: cci0_active {
mux {
/* CLK, DATA */
diff --git a/arch/arm/boot/dts/qcom/msm8996-pm.dtsi b/arch/arm/boot/dts/qcom/msm8996-pm.dtsi
index 82ac7271e9a8..df7cd79a7002 100644
--- a/arch/arm/boot/dts/qcom/msm8996-pm.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-pm.dtsi
@@ -161,7 +161,7 @@
qcom,psci-cpu-mode = <4>;
qcom,latency-us = <80>;
qcom,ss-power = <196>;
- qcom,energy-overhead = <45300>;
+ qcom,energy-overhead = <62248>;
qcom,time-overhead = <210>;
qcom,reset-level =
<LPM_RESET_LVL_PC>;
@@ -250,7 +250,7 @@
qcom,psci-cpu-mode = <4>;
qcom,latency-us = <80>;
qcom,ss-power = <196>;
- qcom,energy-overhead = <45300>;
+ qcom,energy-overhead = <62248>;
qcom,time-overhead = <210>;
qcom,reset-level =
<LPM_RESET_LVL_PC>;
diff --git a/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts b/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts
index ac4d78f2a97c..ad38744e4490 100644
--- a/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts
@@ -12,6 +12,7 @@
/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
#include "msm8996pro.dtsi"
#include "msm8996-pm8994.dtsi"
#include "msm8996-agave-adp.dtsi"
@@ -40,6 +41,10 @@
};
};
+&slim_msm {
+ status = "disabled";
+};
+
&pm8994_mpps {
mpp@a500 { /* MPP 6 */
qcom,mode = <1>; /* Digital output */
@@ -59,6 +64,19 @@
status = "ok";
};
+&sdhc_2 {
+ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on_sbc>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off
+ &sdc2_cd_on_sbc>;
+};
+
+&i2c_7 {
+ silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/
+ status = "disabled";
+ };
+};
+
&gfx_cpr {
vdd-supply = <&hl7509_vreg>;
qcom,cpr-step-quot-init-min = <20>;
diff --git a/arch/arm/boot/dts/qcom/msm8996pro.dtsi b/arch/arm/boot/dts/qcom/msm8996pro.dtsi
index 514bddbbd557..797df2b5a458 100644
--- a/arch/arm/boot/dts/qcom/msm8996pro.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996pro.dtsi
@@ -54,9 +54,23 @@
qcom,cpr-corner-fmax-map =
/* Speed bin 0 */
<1 6 9 14 19>,
+ <1 6 9 14 19>,
+ <3 6 9 14 19>,
+ <3 6 9 14 19>,
+ <3 6 9 14 19>,
+ <3 6 9 14 19>,
+ <3 6 9 14 19>,
+ <3 6 9 14 19>,
/* Speed bin 1 */
- <1 6 9 14 19>;
+ <1 6 9 14 19>,
+ <1 6 9 14 19>,
+ <3 6 9 14 19>,
+ <3 6 9 14 19>,
+ <3 6 9 14 19>,
+ <3 6 9 14 19>,
+ <3 6 9 14 19>,
+ <3 6 9 14 19>;
qcom,cpr-voltage-ceiling =
/* Speed bin 0 */
@@ -336,9 +350,23 @@
qcom,cpr-corner-fmax-map =
/* Speed bin 0 */
<1 7 10 15 27>,
+ <1 7 10 15 27>,
+ <4 7 10 15 27>,
+ <4 7 10 15 27>,
+ <4 7 10 15 27>,
+ <4 7 10 15 27>,
+ <4 7 10 15 27>,
+ <4 7 10 15 27>,
/* Speed bin 1 */
- <1 7 10 15 25>;
+ <1 7 10 15 25>,
+ <1 7 10 15 25>,
+ <4 7 10 15 25>,
+ <4 7 10 15 25>,
+ <4 7 10 15 25>,
+ <4 7 10 15 25>,
+ <4 7 10 15 25>,
+ <4 7 10 15 25>;
qcom,cpr-voltage-ceiling =
/* Speed bin 0 */
@@ -974,6 +1002,9 @@
&soc {
qcom,msm-thermal {
+ qcom,poll-ms = <50>;
+ qcom,limit-temp = <80>;
+ qcom,core-limit-temp = <90>;
qcom,vdd-gfx-rstr{
qcom,levels = <6 8 9>; /* Nominal, Turbo, Turbo_L1 */
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi
index f2850e4f968a..72c8801b2a3e 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi
@@ -77,6 +77,8 @@
qcom,highest-bank-bit = <15>;
+ qcom,snapshot-size = <1048576>; //bytes
+
clocks = <&clock_gpu clk_gpucc_gfx3d_clk>,
<&clock_gcc clk_gcc_gpu_cfg_ahb_clk>,
<&clock_gpu clk_gpucc_rbbmtimer_clk>,
diff --git a/arch/arm/configs/mdm-perf_defconfig b/arch/arm/configs/mdm-perf_defconfig
index a5211c534acc..3230a239a1bb 100644
--- a/arch/arm/configs/mdm-perf_defconfig
+++ b/arch/arm/configs/mdm-perf_defconfig
@@ -207,7 +207,8 @@ CONFIG_USB_NET_SMSC95XX=y
CONFIG_USBNET_IPA_BRIDGE=y
CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CNSS_CRYPTO=y
-CONFIG_CNSS_PCI=y
+CONFIG_CNSS=y
+CONFIG_CLD_HL_SDIO_CORE=y
CONFIG_CLD_LL_CORE=y
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=y
diff --git a/arch/arm/configs/mdm9607-perf_defconfig b/arch/arm/configs/mdm9607-perf_defconfig
index a71038991d14..2f81192af342 100644
--- a/arch/arm/configs/mdm9607-perf_defconfig
+++ b/arch/arm/configs/mdm9607-perf_defconfig
@@ -194,7 +194,7 @@ CONFIG_PPP=y
CONFIG_PPP_ASYNC=y
CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CNSS_CRYPTO=y
-CONFIG_CNSS_SDIO=y
+CONFIG_CNSS=y
CONFIG_CLD_HL_SDIO_CORE=y
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=y
diff --git a/arch/arm/configs/mdm9607_defconfig b/arch/arm/configs/mdm9607_defconfig
index 54f9a4b7df72..a26399501901 100644
--- a/arch/arm/configs/mdm9607_defconfig
+++ b/arch/arm/configs/mdm9607_defconfig
@@ -194,7 +194,7 @@ CONFIG_PPP=y
CONFIG_PPP_ASYNC=y
CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CNSS_CRYPTO=y
-CONFIG_CNSS_SDIO=y
+CONFIG_CNSS=y
CONFIG_CLD_HL_SDIO_CORE=y
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=y
diff --git a/arch/arm/configs/mdm_defconfig b/arch/arm/configs/mdm_defconfig
index fa0e179b99e2..0127b003fa53 100644
--- a/arch/arm/configs/mdm_defconfig
+++ b/arch/arm/configs/mdm_defconfig
@@ -206,7 +206,8 @@ CONFIG_USB_NET_SMSC95XX=y
CONFIG_USBNET_IPA_BRIDGE=y
CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CNSS_CRYPTO=y
-CONFIG_CNSS_PCI=y
+CONFIG_CNSS=y
+CONFIG_CLD_HL_SDIO_CORE=y
CONFIG_CLD_LL_CORE=y
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=y
diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig
index adc9cc2ab586..a5ea0da55455 100644
--- a/arch/arm/configs/msm8937-perf_defconfig
+++ b/arch/arm/configs/msm8937-perf_defconfig
@@ -232,6 +232,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_UID_STAT=y
CONFIG_QSEECOM=y
CONFIG_HDCP_QSEECOM=y
+CONFIG_UID_CPUTIME=y
CONFIG_USB_EXT_TYPE_C_PERICOM=y
CONFIG_MSM_ULTRASOUND=y
CONFIG_SCSI=y
@@ -294,7 +295,11 @@ CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_GEN_VKEYS=y
CONFIG_TOUCHSCREEN_FT5X06=y
CONFIG_FT_SECURE_TOUCH=y
+CONFIG_TOUCHSCREEN_GT9XX=y
CONFIG_TOUCHSCREEN_MAXIM_STI=y
+CONFIG_GT9XX_TOUCHPANEL_DRIVER=y
+CONFIG_GT9XX_TOUCHPANEL_UPDATE=y
+CONFIG_GT9XX_TOUCHPANEL_DEBUG=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_KEYCHORD=y
diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig
index c1f33e636b57..02cc623139aa 100644
--- a/arch/arm/configs/msm8937_defconfig
+++ b/arch/arm/configs/msm8937_defconfig
@@ -234,6 +234,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_UID_STAT=y
CONFIG_QSEECOM=y
CONFIG_HDCP_QSEECOM=y
+CONFIG_UID_CPUTIME=y
CONFIG_USB_EXT_TYPE_C_PERICOM=y
CONFIG_MSM_ULTRASOUND=y
CONFIG_SCSI=y
@@ -296,7 +297,11 @@ CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_GEN_VKEYS=y
CONFIG_TOUCHSCREEN_FT5X06=y
CONFIG_FT_SECURE_TOUCH=y
+CONFIG_TOUCHSCREEN_GT9XX=y
CONFIG_TOUCHSCREEN_MAXIM_STI=y
+CONFIG_GT9XX_TOUCHPANEL_DRIVER=y
+CONFIG_GT9XX_TOUCHPANEL_UPDATE=y
+CONFIG_GT9XX_TOUCHPANEL_DEBUG=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_KEYCHORD=y
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index 5206d5b29b72..d8c2de72e8af 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -190,6 +190,13 @@ static int __init parse_cluster(struct device_node *cluster, int depth)
return 0;
}
+static DEFINE_PER_CPU(unsigned long, cpu_efficiency) = SCHED_CAPACITY_SCALE;
+
+unsigned long arch_get_cpu_efficiency(int cpu)
+{
+ return per_cpu(cpu_efficiency, cpu);
+}
+
#ifdef CONFIG_OF
struct cpu_efficiency {
const char *compatible;
@@ -266,6 +273,7 @@ static int __init parse_dt_topology(void)
for_each_possible_cpu(cpu) {
const u32 *rate;
int len;
+ u32 efficiency;
/* too early to use cpu->of_node */
cn = of_get_cpu_node(cpu, NULL);
@@ -274,12 +282,26 @@ static int __init parse_dt_topology(void)
continue;
}
- for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
- if (of_device_is_compatible(cn, cpu_eff->compatible))
- break;
+ /*
+ * The CPU efficiency value passed from the device tree
+ * overrides the value defined in the table_efficiency[]
+ */
+ if (of_property_read_u32(cn, "efficiency", &efficiency) < 0) {
+
+ for (cpu_eff = table_efficiency;
+ cpu_eff->compatible; cpu_eff++)
- if (cpu_eff->compatible == NULL)
- continue;
+ if (of_device_is_compatible(cn,
+ cpu_eff->compatible))
+ break;
+
+ if (cpu_eff->compatible == NULL)
+ continue;
+
+ efficiency = cpu_eff->efficiency;
+ }
+
+ per_cpu(cpu_efficiency, cpu) = efficiency;
rate = of_get_property(cn, "clock-frequency", &len);
if (!rate || len != 4) {
@@ -288,7 +310,7 @@ static int __init parse_dt_topology(void)
continue;
}
- capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
+ capacity = ((be32_to_cpup(rate)) >> 20) * efficiency;
/* Save min capacity of the system */
if (capacity < min_capacity)
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index bbdbe2dcc87d..407dc786583a 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -183,9 +183,8 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
{
unsigned long random_factor = 0UL;
- if ((current->flags & PF_RANDOMIZE) &&
- !(current->personality & ADDR_NO_RANDOMIZE))
- random_factor = (get_random_long() & ((1UL << mmap_rnd_bits) - 1)) << PAGE_SHIFT;
+ if (current->flags & PF_RANDOMIZE)
+ random_factor = arch_mmap_rnd();
if (mmap_is_legacy()) {
mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
diff --git a/arch/arm64/configs/msm-auto-perf_defconfig b/arch/arm64/configs/msm-auto-perf_defconfig
index 87f683dc143b..7ad6cc91c32d 100644
--- a/arch/arm64/configs/msm-auto-perf_defconfig
+++ b/arch/arm64/configs/msm-auto-perf_defconfig
@@ -275,7 +275,7 @@ CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CNSS_CRYPTO=y
CONFIG_ATH_CARDS=y
CONFIG_WIL6210=m
-CONFIG_CNSS_PCI=y
+CONFIG_CNSS=y
CONFIG_CLD_LL_CORE=y
CONFIG_BUS_AUTO_SUSPEND=y
CONFIG_INPUT_EVDEV=y
diff --git a/arch/arm64/configs/msm-auto_defconfig b/arch/arm64/configs/msm-auto_defconfig
index 583337fc1f12..f018e4f8f1f3 100644
--- a/arch/arm64/configs/msm-auto_defconfig
+++ b/arch/arm64/configs/msm-auto_defconfig
@@ -276,7 +276,7 @@ CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CNSS_CRYPTO=y
CONFIG_ATH_CARDS=y
CONFIG_WIL6210=m
-CONFIG_CNSS_PCI=y
+CONFIG_CNSS=y
CONFIG_CLD_LL_CORE=y
CONFIG_BUS_AUTO_SUSPEND=y
CONFIG_INPUT_EVDEV=y
diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig
index e410fe3d8509..975ac5a6bf9c 100644
--- a/arch/arm64/configs/msm-perf_defconfig
+++ b/arch/arm64/configs/msm-perf_defconfig
@@ -272,7 +272,7 @@ CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CNSS_CRYPTO=y
CONFIG_ATH_CARDS=y
CONFIG_WIL6210=m
-CONFIG_CNSS_PCI=y
+CONFIG_CNSS=y
CONFIG_CLD_LL_CORE=y
CONFIG_BUS_AUTO_SUSPEND=y
CONFIG_INPUT_EVDEV=y
diff --git a/arch/arm64/configs/msm8937-perf_defconfig b/arch/arm64/configs/msm8937-perf_defconfig
index 324e94869e6b..1f240a622751 100644
--- a/arch/arm64/configs/msm8937-perf_defconfig
+++ b/arch/arm64/configs/msm8937-perf_defconfig
@@ -228,6 +228,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_UID_STAT=y
CONFIG_QSEECOM=y
CONFIG_HDCP_QSEECOM=y
+CONFIG_UID_CPUTIME=y
CONFIG_USB_EXT_TYPE_C_PERICOM=y
CONFIG_MSM_ULTRASOUND=y
CONFIG_SCSI=y
@@ -271,7 +272,7 @@ CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CNSS_CRYPTO=y
CONFIG_ATH_CARDS=y
CONFIG_WIL6210=m
-CONFIG_CNSS_PCI=y
+CONFIG_CNSS=y
CONFIG_CLD_LL_CORE=y
CONFIG_BUS_AUTO_SUSPEND=y
CONFIG_INPUT_EVDEV=y
diff --git a/arch/arm64/configs/msm8937_defconfig b/arch/arm64/configs/msm8937_defconfig
index 4860e0d79681..84302b3d2330 100644
--- a/arch/arm64/configs/msm8937_defconfig
+++ b/arch/arm64/configs/msm8937_defconfig
@@ -228,6 +228,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_UID_STAT=y
CONFIG_QSEECOM=y
CONFIG_HDCP_QSEECOM=y
+CONFIG_UID_CPUTIME=y
CONFIG_USB_EXT_TYPE_C_PERICOM=y
CONFIG_MSM_ULTRASOUND=y
CONFIG_SCSI=y
@@ -271,7 +272,7 @@ CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CNSS_CRYPTO=y
CONFIG_ATH_CARDS=y
CONFIG_WIL6210=m
-CONFIG_CNSS_PCI=y
+CONFIG_CNSS=y
CONFIG_CLD_LL_CORE=y
CONFIG_BUS_AUTO_SUSPEND=y
CONFIG_INPUT_EVDEV=y
diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig
index 6c16bc386054..7de6330cf672 100644
--- a/arch/arm64/configs/msm_defconfig
+++ b/arch/arm64/configs/msm_defconfig
@@ -273,7 +273,7 @@ CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CNSS_CRYPTO=y
CONFIG_ATH_CARDS=y
CONFIG_WIL6210=m
-CONFIG_CNSS_PCI=y
+CONFIG_CNSS=y
CONFIG_CLD_LL_CORE=y
CONFIG_BUS_AUTO_SUSPEND=y
CONFIG_INPUT_EVDEV=y
diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig
index 09a7167070e2..2bb7a0a8eda5 100644
--- a/arch/arm64/configs/msmcortex-perf_defconfig
+++ b/arch/arm64/configs/msmcortex-perf_defconfig
@@ -478,7 +478,6 @@ CONFIG_SWITCH=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_EDAC_CORTEX_ARM64=y
-CONFIG_EDAC_CORTEX_ARM64_PANIC_ON_CE=y
CONFIG_EDAC_CORTEX_ARM64_PANIC_ON_UE=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_QPNP=y
diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig
index a52eba470c4e..932024425806 100644
--- a/arch/arm64/configs/msmcortex_defconfig
+++ b/arch/arm64/configs/msmcortex_defconfig
@@ -481,7 +481,6 @@ CONFIG_SWITCH=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_EDAC_CORTEX_ARM64=y
-CONFIG_EDAC_CORTEX_ARM64_PANIC_ON_CE=y
CONFIG_EDAC_CORTEX_ARM64_PANIC_ON_UE=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_QPNP=y
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 6feb103b5075..e0204616f1bb 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -280,6 +280,7 @@ static void __init parse_dt_cpu_power(void)
for_each_possible_cpu(cpu) {
const u32 *rate;
int len;
+ u32 efficiency;
/* Too early to use cpu->of_node */
cn = of_get_cpu_node(cpu, NULL);
@@ -288,16 +289,29 @@ static void __init parse_dt_cpu_power(void)
continue;
}
- for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
- if (of_device_is_compatible(cn, cpu_eff->compatible))
- break;
+ /*
+ * The CPU efficiency value passed from the device tree
+ * overrides the value defined in the table_efficiency[]
+ */
+ if (of_property_read_u32(cn, "efficiency", &efficiency) < 0) {
- if (cpu_eff->compatible == NULL) {
- pr_warn("%s: Unknown CPU type\n", cn->full_name);
- continue;
+ for (cpu_eff = table_efficiency;
+ cpu_eff->compatible; cpu_eff++)
+
+ if (of_device_is_compatible(cn,
+ cpu_eff->compatible))
+ break;
+
+ if (cpu_eff->compatible == NULL) {
+ pr_warn("%s: Unknown CPU type\n",
+ cn->full_name);
+ continue;
+ }
+
+ efficiency = cpu_eff->efficiency;
}
- per_cpu(cpu_efficiency, cpu) = cpu_eff->efficiency;
+ per_cpu(cpu_efficiency, cpu) = efficiency;
rate = of_get_property(cn, "clock-frequency", &len);
if (!rate || len != 4) {
@@ -306,7 +320,7 @@ static void __init parse_dt_cpu_power(void)
continue;
}
- capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
+ capacity = ((be32_to_cpup(rate)) >> 20) * efficiency;
/* Save min capacity of the system */
if (capacity < min_capacity)
diff --git a/drivers/base/dma-removed.c b/drivers/base/dma-removed.c
index 6a75a16e2fae..ecb069a46f38 100644
--- a/drivers/base/dma-removed.c
+++ b/drivers/base/dma-removed.c
@@ -181,15 +181,16 @@ static void removed_region_fixup(struct removed_region *dma_mem, int index)
{
unsigned long fixup_size;
unsigned long base_pfn;
+ unsigned long flags;
if (index > dma_mem->nr_pages)
return;
/* carve-out */
- memblock_region_resize_late_begin();
+ flags = memblock_region_resize_late_begin();
memblock_free(dma_mem->base, dma_mem->nr_pages * PAGE_SIZE);
memblock_remove(dma_mem->base, index * PAGE_SIZE);
- memblock_region_resize_late_end();
+ memblock_region_resize_late_end(flags);
/* clear page-mappings */
base_pfn = dma_mem->base >> PAGE_SHIFT;
diff --git a/drivers/bluetooth/bluetooth-power.c b/drivers/bluetooth/bluetooth-power.c
index 6bcd6a77c631..3f2d53fa5a90 100644
--- a/drivers/bluetooth/bluetooth-power.c
+++ b/drivers/bluetooth/bluetooth-power.c
@@ -295,7 +295,7 @@ static const struct rfkill_ops bluetooth_power_rfkill_ops = {
.set_block = bluetooth_toggle_radio,
};
-#ifdef CONFIG_CNSS_PCI
+#if defined(CONFIG_CNSS) && defined(CONFIG_CLD_LL_CORE)
static ssize_t enable_extldo(struct device *dev, struct device_attribute *attr,
char *buf)
{
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 406454ae0ee7..9af276fff273 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -424,6 +424,7 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map)
if (!map)
return;
+ fl = map->fl;
if (map->flags == ADSP_MMAP_HEAP_ADDR) {
spin_lock(&me->hlock);
map->refs--;
@@ -431,18 +432,6 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map)
hlist_del_init(&map->hn);
spin_unlock(&me->hlock);
} else {
- int destVM[1] = {VMID_HLOS};
- int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
-
- fl = map->fl;
- vmid = fl->apps->channel[fl->cid].vmid;
- if (vmid) {
- int srcVM[2] = {VMID_HLOS, vmid};
-
- hyp_assign_phys(map->phys, buf_page_size(map->size),
- srcVM, 2, destVM, destVMperm, 1);
- }
-
spin_lock(&fl->hlock);
map->refs--;
if (!map->refs)
@@ -465,6 +454,9 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map)
&(map->va), map->phys, &attrs);
}
} else {
+ int destVM[1] = {VMID_HLOS};
+ int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
+
if (!IS_ERR_OR_NULL(map->handle))
ion_free(fl->apps->client, map->handle);
if (fl->sctx->smmu.enabled) {
@@ -474,6 +466,14 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map)
map->table->nents, DMA_BIDIRECTIONAL,
map->buf);
}
+ vmid = fl->apps->channel[fl->cid].vmid;
+ if (vmid && map->phys) {
+ int srcVM[2] = {VMID_HLOS, vmid};
+
+ hyp_assign_phys(map->phys, buf_page_size(map->size),
+ srcVM, 2, destVM, destVMperm, 1);
+ }
+
if (!IS_ERR_OR_NULL(map->table))
dma_buf_unmap_attachment(map->attach, map->table,
DMA_BIDIRECTIONAL);
@@ -552,9 +552,12 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, uintptr_t va,
goto bail;
map->uncached = !ION_IS_CACHED(flags);
map->phys = sg_dma_address(map->table->sgl);
- map->size = sg_dma_len(map->table->sgl);
- if (sess->smmu.cb)
+ if (sess->smmu.cb) {
map->phys += ((uint64_t)sess->smmu.cb << 32);
+ map->size = sg_dma_len(map->table->sgl);
+ } else {
+ map->size = buf_page_size(len);
+ }
vmid = fl->apps->channel[fl->cid].vmid;
if (vmid) {
int srcVM[1] = {VMID_HLOS};
diff --git a/drivers/clk/msm/clock-gcc-8996.c b/drivers/clk/msm/clock-gcc-8996.c
index 5cd45a4eadc1..a0f43c3cf908 100644
--- a/drivers/clk/msm/clock-gcc-8996.c
+++ b/drivers/clk/msm/clock-gcc-8996.c
@@ -1339,9 +1339,11 @@ static struct rcg_clk pdm2_clk_src = {
},
};
-/* Frequency table might change later */
static struct clk_freq_tbl ftbl_qspi_ser_clk_src[] = {
- F( 192000000, gpll4_out_main, 2, 0, 0),
+ F( 75000000, gpll0_out_main, 8, 0, 0),
+ F( 150000000, gpll0_out_main, 4, 0, 0),
+ F( 256000000, gpll4_out_main, 1.5, 0, 0),
+ F( 300000000, gpll0_out_main, 2, 0, 0),
F_END
};
diff --git a/drivers/cpuidle/lpm-levels-of.c b/drivers/cpuidle/lpm-levels-of.c
index f4ae70ac9315..750511a43b54 100644
--- a/drivers/cpuidle/lpm-levels-of.c
+++ b/drivers/cpuidle/lpm-levels-of.c
@@ -38,25 +38,87 @@ static const struct lpm_type_str lpm_types[] = {
{SUSPEND, "suspend_enabled"},
};
+static DEFINE_PER_CPU(uint32_t *, max_residency);
static struct lpm_level_avail *cpu_level_available[NR_CPUS];
static struct platform_device *lpm_pdev;
-static void *get_avail_val(struct kobject *kobj, struct kobj_attribute *attr)
+static void *get_enabled_ptr(struct kobj_attribute *attr,
+ struct lpm_level_avail *avail)
{
void *arg = NULL;
+
+ if (!strcmp(attr->attr.name, lpm_types[IDLE].str))
+ arg = (void *) &avail->idle_enabled;
+ else if (!strcmp(attr->attr.name, lpm_types[SUSPEND].str))
+ arg = (void *) &avail->suspend_enabled;
+
+ return arg;
+}
+
+static struct lpm_level_avail *get_avail_ptr(struct kobject *kobj,
+ struct kobj_attribute *attr)
+{
struct lpm_level_avail *avail = NULL;
- if (!strcmp(attr->attr.name, lpm_types[IDLE].str)) {
+ if (!strcmp(attr->attr.name, lpm_types[IDLE].str))
avail = container_of(attr, struct lpm_level_avail,
idle_enabled_attr);
- arg = (void *) &avail->idle_enabled;
- } else if (!strcmp(attr->attr.name, lpm_types[SUSPEND].str)) {
+ else if (!strcmp(attr->attr.name, lpm_types[SUSPEND].str))
avail = container_of(attr, struct lpm_level_avail,
suspend_enabled_attr);
- arg = (void *) &avail->suspend_enabled;
+
+ return avail;
+}
+
+static void set_optimum_cpu_residency(struct lpm_cpu *cpu, int cpu_id,
+ bool probe_time)
+{
+ int i, j;
+ bool mode_avail;
+ uint32_t *residency = per_cpu(max_residency, cpu_id);
+
+ for (i = 0; i < cpu->nlevels; i++) {
+ struct power_params *pwr = &cpu->levels[i].pwr;
+
+ residency[i] = ~0;
+ for (j = i + 1; j < cpu->nlevels; j++) {
+ mode_avail = probe_time ||
+ lpm_cpu_mode_allow(cpu_id, j, true);
+
+ if (mode_avail &&
+ (residency[i] > pwr->residencies[j]) &&
+ (pwr->residencies[j] != 0))
+ residency[i] = pwr->residencies[j];
+ }
}
+}
- return arg;
+static void set_optimum_cluster_residency(struct lpm_cluster *cluster,
+ bool probe_time)
+{
+ int i, j;
+ bool mode_avail;
+
+ for (i = 0; i < cluster->nlevels; i++) {
+ struct power_params *pwr = &cluster->levels[i].pwr;
+
+ pwr->max_residency = ~0;
+ for (j = 0; j < cluster->nlevels; j++) {
+ if (i >= j)
+ mode_avail = probe_time ||
+ lpm_cluster_mode_allow(cluster, i,
+ true);
+ if (mode_avail &&
+ (pwr->max_residency > pwr->residencies[j]) &&
+ (pwr->residencies[j] != 0))
+ pwr->max_residency = pwr->residencies[j];
+ }
+ }
+}
+
+uint32_t *get_per_cpu_max_residency(int cpu)
+{
+ return per_cpu(max_residency, cpu);
}
ssize_t lpm_enable_show(struct kobject *kobj, struct kobj_attribute *attr,
@@ -65,7 +127,7 @@ ssize_t lpm_enable_show(struct kobject *kobj, struct kobj_attribute *attr,
int ret = 0;
struct kernel_param kp;
- kp.arg = get_avail_val(kobj, attr);
+ kp.arg = get_enabled_ptr(attr, get_avail_ptr(kobj, attr));
ret = param_get_bool(buf, &kp);
if (ret > 0) {
strlcat(buf, "\n", PAGE_SIZE);
@@ -80,15 +142,23 @@ ssize_t lpm_enable_store(struct kobject *kobj, struct kobj_attribute *attr,
{
int ret = 0;
struct kernel_param kp;
+ struct lpm_level_avail *avail;
- kp.arg = get_avail_val(kobj, attr);
+ avail = get_avail_ptr(kobj, attr);
+ kp.arg = get_enabled_ptr(attr, avail);
ret = param_set_bool(buf, &kp);
+ if (avail->cpu_node)
+ set_optimum_cpu_residency(avail->data, avail->idx, false);
+ else
+ set_optimum_cluster_residency(avail->data, false);
+
return ret ? ret : len;
}
static int create_lvl_avail_nodes(const char *name,
- struct kobject *parent, struct lpm_level_avail *avail)
+ struct kobject *parent, struct lpm_level_avail *avail,
+ void *data, int index, bool cpu_node)
{
struct attribute_group *attr_group = NULL;
struct attribute **attr = NULL;
@@ -139,6 +209,9 @@ static int create_lvl_avail_nodes(const char *name,
avail->idle_enabled = true;
avail->suspend_enabled = true;
avail->kobj = kobj;
+ avail->data = data;
+ avail->idx = index;
+ avail->cpu_node = cpu_node;
return ret;
@@ -181,7 +254,8 @@ static int create_cpu_lvl_nodes(struct lpm_cluster *p, struct kobject *parent)
for (i = 0; i < p->cpu->nlevels; i++) {
ret = create_lvl_avail_nodes(p->cpu->levels[i].name,
- cpu_kobj[cpu_idx], &level_list[i]);
+ cpu_kobj[cpu_idx], &level_list[i],
+ (void *)p->cpu, cpu, true);
if (ret)
goto release_kobj;
}
@@ -215,7 +289,8 @@ int create_cluster_lvl_nodes(struct lpm_cluster *p, struct kobject *kobj)
for (i = 0; i < p->nlevels; i++) {
ret = create_lvl_avail_nodes(p->levels[i].level_name,
- cluster_kobj, &p->levels[i].available);
+ cluster_kobj, &p->levels[i].available,
+ (void *)p, 0, false);
if (ret)
return ret;
}
@@ -421,6 +496,9 @@ static int parse_power_params(struct device_node *node,
key = "qcom,time-overhead";
ret = of_property_read_u32(node, key, &pwr->time_overhead_us);
+ if (ret)
+ goto fail;
+
fail:
if (ret)
pr_err("%s(): %s Error reading %s\n", __func__, node->name,
@@ -615,11 +693,31 @@ static int get_cpumask_for_node(struct device_node *node, struct cpumask *mask)
return 0;
}
+static int calculate_residency(struct power_params *base_pwr,
+ struct power_params *next_pwr)
+{
+ int32_t residency = (int32_t)(next_pwr->energy_overhead -
+ base_pwr->energy_overhead) -
+ ((int32_t)(next_pwr->ss_power * next_pwr->time_overhead_us)
+ - (int32_t)(base_pwr->ss_power * base_pwr->time_overhead_us));
+
+ residency /= (int32_t)(base_pwr->ss_power - next_pwr->ss_power);
+
+ if (residency < 0) {
+ __WARN_printf("%s: Incorrect power attributes for LPM\n",
+ __func__);
+ return next_pwr->time_overhead_us;
+ }
+
+ return residency < next_pwr->time_overhead_us ?
+ next_pwr->time_overhead_us : residency;
+}
+
static int parse_cpu_levels(struct device_node *node, struct lpm_cluster *c)
{
struct device_node *n;
int ret = -ENOMEM;
- int i;
+ int i, j;
char *key;
c->cpu = devm_kzalloc(&lpm_pdev->dev, sizeof(*c->cpu), GFP_KERNEL);
@@ -676,6 +774,22 @@ static int parse_cpu_levels(struct device_node *node, struct lpm_cluster *c)
else if (ret)
goto failed;
}
+ for (i = 0; i < c->cpu->nlevels; i++) {
+ for (j = 0; j < c->cpu->nlevels; j++) {
+ if (i >= j) {
+ c->cpu->levels[i].pwr.residencies[j] = 0;
+ continue;
+ }
+
+ c->cpu->levels[i].pwr.residencies[j] =
+ calculate_residency(&c->cpu->levels[i].pwr,
+ &c->cpu->levels[j].pwr);
+
+ pr_err("%s: idx %d %u\n", __func__, j,
+ c->cpu->levels[i].pwr.residencies[j]);
+ }
+ }
+
return 0;
failed:
for (i = 0; i < c->cpu->nlevels; i++) {
@@ -732,6 +846,7 @@ struct lpm_cluster *parse_cluster(struct device_node *node,
struct device_node *n;
char *key;
int ret = 0;
+ int i, j;
c = devm_kzalloc(&lpm_pdev->dev, sizeof(*c), GFP_KERNEL);
if (!c)
@@ -789,6 +904,16 @@ struct lpm_cluster *parse_cluster(struct device_node *node,
goto failed_parse_cluster;
c->aff_level = 1;
+
+ for_each_cpu(i, &c->child_cpus) {
+ per_cpu(max_residency, i) = devm_kzalloc(
+ &lpm_pdev->dev,
+ sizeof(uint32_t) * c->cpu->nlevels,
+ GFP_KERNEL);
+ if (!per_cpu(max_residency, i))
+ return ERR_PTR(-ENOMEM);
+ set_optimum_cpu_residency(c->cpu, i, true);
+ }
}
}
@@ -797,6 +922,17 @@ struct lpm_cluster *parse_cluster(struct device_node *node,
else
c->last_level = c->nlevels-1;
+ for (i = 0; i < c->nlevels; i++) {
+ for (j = 0; j < c->nlevels; j++) {
+ if (i >= j) {
+ c->levels[i].pwr.residencies[j] = 0;
+ continue;
+ }
+ c->levels[i].pwr.residencies[j] = calculate_residency(
+ &c->levels[i].pwr, &c->levels[j].pwr);
+ }
+ }
+ set_optimum_cluster_residency(c, true);
return c;
failed_parse_cluster:
diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c
index 35ed569c21a5..3eeafdfbee43 100644
--- a/drivers/cpuidle/lpm-levels.c
+++ b/drivers/cpuidle/lpm-levels.c
@@ -453,18 +453,15 @@ static int cpu_power_select(struct cpuidle_device *dev,
struct lpm_cpu *cpu)
{
int best_level = -1;
- uint32_t best_level_pwr = ~0U;
uint32_t latency_us = pm_qos_request_for_cpu(PM_QOS_CPU_DMA_LATENCY,
dev->cpu);
uint32_t sleep_us =
(uint32_t)(ktime_to_us(tick_nohz_get_sleep_length()));
uint32_t modified_time_us = 0;
uint32_t next_event_us = 0;
- uint32_t pwr;
int i;
uint32_t lvl_latency_us = 0;
- uint32_t lvl_overhead_us = 0;
- uint32_t lvl_overhead_energy = 0;
+ uint32_t *residency = get_per_cpu_max_residency(dev->cpu);
if (!cpu)
return -EINVAL;
@@ -488,12 +485,8 @@ static int cpu_power_select(struct cpuidle_device *dev,
lvl_latency_us = pwr_params->latency_us;
- lvl_overhead_us = pwr_params->time_overhead_us;
-
- lvl_overhead_energy = pwr_params->energy_overhead;
-
if (latency_us < lvl_latency_us)
- continue;
+ break;
if (next_event_us) {
if (next_event_us < lvl_latency_us)
@@ -504,32 +497,15 @@ static int cpu_power_select(struct cpuidle_device *dev,
next_wakeup_us = next_event_us - lvl_latency_us;
}
- if (next_wakeup_us <= pwr_params->time_overhead_us)
- continue;
-
- /*
- * If wakeup time greater than overhead by a factor of 1000
- * assume that core steady state power dominates the power
- * equation
- */
- if ((next_wakeup_us >> 10) > lvl_overhead_us) {
- pwr = pwr_params->ss_power;
- } else {
- pwr = pwr_params->ss_power;
- pwr -= (lvl_overhead_us * pwr_params->ss_power) /
- next_wakeup_us;
- pwr += pwr_params->energy_overhead / next_wakeup_us;
- }
-
- if (best_level_pwr >= pwr) {
+ if (next_wakeup_us <= residency[i]) {
best_level = i;
- best_level_pwr = pwr;
if (next_event_us && next_event_us < sleep_us &&
(mode != MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT))
modified_time_us
= next_event_us - lvl_latency_us;
else
modified_time_us = 0;
+ break;
}
}
@@ -587,8 +563,6 @@ static int cluster_select(struct lpm_cluster *cluster, bool from_idle)
{
int best_level = -1;
int i;
- uint32_t best_level_pwr = ~0U;
- uint32_t pwr;
struct cpumask mask;
uint32_t latency_us = ~0U;
uint32_t sleep_us;
@@ -640,18 +614,9 @@ static int cluster_select(struct lpm_cluster *cluster, bool from_idle)
if (level->notify_rpm && msm_rpm_waiting_for_ack())
continue;
- if ((sleep_us >> 10) > pwr_params->time_overhead_us) {
- pwr = pwr_params->ss_power;
- } else {
- pwr = pwr_params->ss_power;
- pwr -= (pwr_params->time_overhead_us *
- pwr_params->ss_power) / sleep_us;
- pwr += pwr_params->energy_overhead / sleep_us;
- }
-
- if (best_level_pwr >= pwr) {
+ if (sleep_us <= pwr_params->max_residency) {
best_level = i;
- best_level_pwr = pwr;
+ break;
}
}
diff --git a/drivers/cpuidle/lpm-levels.h b/drivers/cpuidle/lpm-levels.h
index 8e05336be21a..f6979c4d4d9f 100644
--- a/drivers/cpuidle/lpm-levels.h
+++ b/drivers/cpuidle/lpm-levels.h
@@ -27,6 +27,8 @@ struct power_params {
uint32_t ss_power; /* Steady state power */
uint32_t energy_overhead; /* Enter + exit over head */
uint32_t time_overhead_us; /* Enter + exit overhead */
+ uint32_t residencies[NR_LPM_LEVELS];
+ uint32_t max_residency;
};
struct lpm_cpu_level {
@@ -55,6 +57,9 @@ struct lpm_level_avail {
struct kobject *kobj;
struct kobj_attribute idle_enabled_attr;
struct kobj_attribute suspend_enabled_attr;
+ void *data;
+ int idx;
+ bool cpu_node;
};
struct lpm_cluster_level {
@@ -119,7 +124,7 @@ bool lpm_cpu_mode_allow(unsigned int cpu,
unsigned int mode, bool from_idle);
bool lpm_cluster_mode_allow(struct lpm_cluster *cluster,
unsigned int mode, bool from_idle);
-
+uint32_t *get_per_cpu_max_residency(int cpu);
extern struct lpm_cluster *lpm_root_node;
#ifdef CONFIG_SMP
diff --git a/drivers/devfreq/governor_spdm_bw_hyp.c b/drivers/devfreq/governor_spdm_bw_hyp.c
index e5e179931811..640af17144df 100644
--- a/drivers/devfreq/governor_spdm_bw_hyp.c
+++ b/drivers/devfreq/governor_spdm_bw_hyp.c
@@ -1,5 +1,5 @@
/*
-*Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+*Copyright (c) 2014-2016, 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
@@ -84,6 +84,10 @@ static irqreturn_t threaded_isr(int irq, void *dev_id)
(int)desc.arg[0], ext_status);
mutex_lock(&devfreqs_lock);
list_for_each_entry(data, &devfreqs, list) {
+ if (data == NULL || data->devfreq == NULL) {
+ pr_err("Spurious interrupts\n");
+ break;
+ }
if (data->spdm_client == desc.ret[0]) {
devfreq_monitor_suspend(data->devfreq);
mutex_lock(&data->devfreq->lock);
diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c
index 27884ff645d8..47e5078292c4 100644
--- a/drivers/edac/edac_device.c
+++ b/drivers/edac/edac_device.c
@@ -411,6 +411,8 @@ void edac_device_workq_setup(struct edac_device_ctl_info *edac_dev,
* to used in the time period calculation
* then calc the number of jiffies that represents
*/
+ if (!msec)
+ msec = 1000;
edac_dev->poll_msec = msec;
edac_dev->delay = msecs_to_jiffies(msec);
@@ -530,7 +532,7 @@ int edac_device_add_device(struct edac_device_ctl_info *edac_dev)
* enable workq processing on this instance,
* default = 1000 msec
*/
- edac_device_workq_setup(edac_dev, 1000);
+ edac_device_workq_setup(edac_dev, edac_dev->poll_msec);
} else {
edac_dev->op_state = OP_RUNNING_INTERRUPT;
}
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 2a3fbd5d08c7..7e36816ee2db 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -177,6 +177,7 @@ static const struct {
{ adreno_is_a530, a530_efuse_speed_bin },
{ adreno_is_a530, a540_efuse_firmware_name },
{ adreno_is_a540v1, a540_efuse_firmware_name },
+ { adreno_is_a505, a530_efuse_speed_bin },
};
static void a5xx_check_features(struct adreno_device *adreno_dev)
diff --git a/drivers/gpu/msm/kgsl_cmdbatch.c b/drivers/gpu/msm/kgsl_cmdbatch.c
index f0d674161036..ceca8b1e1522 100644
--- a/drivers/gpu/msm/kgsl_cmdbatch.c
+++ b/drivers/gpu/msm/kgsl_cmdbatch.c
@@ -539,42 +539,41 @@ static void add_profiling_buffer(struct kgsl_device *device,
int kgsl_cmdbatch_add_ibdesc(struct kgsl_device *device,
struct kgsl_cmdbatch *cmdbatch, struct kgsl_ibdesc *ibdesc)
{
+ uint64_t gpuaddr = (uint64_t) ibdesc->gpuaddr;
+ uint64_t size = (uint64_t) ibdesc->sizedwords << 2;
struct kgsl_memobj_node *mem;
+ /* sanitize the ibdesc ctrl flags */
+ ibdesc->ctrl &= KGSL_IBDESC_MEMLIST | KGSL_IBDESC_PROFILING_BUFFER;
+
+ if (cmdbatch->flags & KGSL_CMDBATCH_MEMLIST &&
+ ibdesc->ctrl & KGSL_IBDESC_MEMLIST) {
+ if (ibdesc->ctrl & KGSL_IBDESC_PROFILING_BUFFER) {
+ add_profiling_buffer(device, cmdbatch,
+ gpuaddr, size, 0, 0);
+ return 0;
+ }
+ }
+
+ if (cmdbatch->flags & (KGSL_CMDBATCH_SYNC | KGSL_CMDBATCH_MARKER))
+ return 0;
+
mem = kmem_cache_alloc(memobjs_cache, GFP_KERNEL);
if (mem == NULL)
return -ENOMEM;
- mem->gpuaddr = (uint64_t) ibdesc->gpuaddr;
- mem->size = (uint64_t) ibdesc->sizedwords << 2;
+ mem->gpuaddr = gpuaddr;
+ mem->size = size;
mem->priv = 0;
mem->id = 0;
mem->offset = 0;
mem->flags = 0;
- /* sanitize the ibdesc ctrl flags */
- ibdesc->ctrl &= KGSL_IBDESC_MEMLIST | KGSL_IBDESC_PROFILING_BUFFER;
-
if (cmdbatch->flags & KGSL_CMDBATCH_MEMLIST &&
ibdesc->ctrl & KGSL_IBDESC_MEMLIST) {
- if (ibdesc->ctrl & KGSL_IBDESC_PROFILING_BUFFER) {
- add_profiling_buffer(device, cmdbatch, mem->gpuaddr,
- mem->size, 0, 0);
- return 0;
- }
-
/* add to the memlist */
list_add_tail(&mem->node, &cmdbatch->memlist);
-
- if (ibdesc->ctrl & KGSL_IBDESC_PROFILING_BUFFER)
- add_profiling_buffer(device, cmdbatch, mem->gpuaddr,
- mem->size, 0, 0);
} else {
- /* Ignore if SYNC or MARKER is specified */
- if (cmdbatch->flags &
- (KGSL_CMDBATCH_SYNC | KGSL_CMDBATCH_MARKER))
- return 0;
-
/* set the preamble flag if directed to */
if (cmdbatch->context->flags & KGSL_CONTEXT_PREAMBLE &&
list_empty(&cmdbatch->cmdlist))
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index b20f1ff895b4..50dcd39fac58 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -852,8 +852,8 @@ kgsl_sharedmem_readl(const struct kgsl_memdesc *memdesc,
if (offsetbytes % sizeof(uint32_t) != 0)
return -EINVAL;
- WARN_ON(offsetbytes + sizeof(uint32_t) > memdesc->size);
- if (offsetbytes + sizeof(uint32_t) > memdesc->size)
+ WARN_ON(offsetbytes > (memdesc->size - sizeof(uint32_t)));
+ if (offsetbytes > (memdesc->size - sizeof(uint32_t)))
return -ERANGE;
rmb();
@@ -875,8 +875,8 @@ kgsl_sharedmem_writel(struct kgsl_device *device,
if (offsetbytes % sizeof(uint32_t) != 0)
return -EINVAL;
- WARN_ON(offsetbytes + sizeof(uint32_t) > memdesc->size);
- if (offsetbytes + sizeof(uint32_t) > memdesc->size)
+ WARN_ON(offsetbytes > (memdesc->size - sizeof(uint32_t)));
+ if (offsetbytes > (memdesc->size - sizeof(uint32_t)))
return -ERANGE;
kgsl_cffdump_write(device,
memdesc->gpuaddr + offsetbytes,
@@ -901,8 +901,8 @@ kgsl_sharedmem_readq(const struct kgsl_memdesc *memdesc,
if (offsetbytes % sizeof(uint32_t) != 0)
return -EINVAL;
- WARN_ON(offsetbytes + sizeof(uint32_t) > memdesc->size);
- if (offsetbytes + sizeof(uint32_t) > memdesc->size)
+ WARN_ON(offsetbytes > (memdesc->size - sizeof(uint32_t)));
+ if (offsetbytes > (memdesc->size - sizeof(uint32_t)))
return -ERANGE;
/*
@@ -928,8 +928,8 @@ kgsl_sharedmem_writeq(struct kgsl_device *device,
if (offsetbytes % sizeof(uint32_t) != 0)
return -EINVAL;
- WARN_ON(offsetbytes + sizeof(uint32_t) > memdesc->size);
- if (offsetbytes + sizeof(uint32_t) > memdesc->size)
+ WARN_ON(offsetbytes > (memdesc->size - sizeof(uint32_t)));
+ if (offsetbytes > (memdesc->size - sizeof(uint32_t)))
return -ERANGE;
kgsl_cffdump_write(device,
lower_32_bits(memdesc->gpuaddr + offsetbytes), src);
diff --git a/drivers/input/touchscreen/gt9xx/goodix_tool.c b/drivers/input/touchscreen/gt9xx/goodix_tool.c
index 291d6d52fd7a..898110fe882c 100644
--- a/drivers/input/touchscreen/gt9xx/goodix_tool.c
+++ b/drivers/input/touchscreen/gt9xx/goodix_tool.c
@@ -1,7 +1,7 @@
/* drivers/input/touchscreen/goodix_tool.c
*
* 2010 - 2012 Goodix Technology.
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, 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 as published by
@@ -69,10 +69,6 @@ static void tool_set_proc_name(char *procname)
char month[4] = {0};
int i = 0, n_month = 1, n_day = 0, n_year = 0, ret;
- snprintf(date, 20, "%s", __DATE__);
-
- /* pr_debug("compile date: %s", date); */
-
ret = sscanf(date, "%s %d %d", month, &n_day, &n_year);
if (!ret)
return;
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c
index 28b8851aade2..d4dc15cea38a 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.c
@@ -1,6 +1,6 @@
/* drivers/input/touchscreen/gt9xx.c
*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*
* Linux Foundation chooses to take subject only to the GPLv2 license
* terms, and distributes only under these terms.
@@ -51,6 +51,8 @@
#include <linux/module.h>
#include <linux/input/mt.h>
#include <linux/debugfs.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
#define GOODIX_DEV_NAME "Goodix-CTP"
#define CFG_MAX_TOUCH_POINTS 5
@@ -650,7 +652,7 @@ void gtp_reset_guitar(struct goodix_ts_data *ts, int ms)
else
gpio_direction_output(ts->pdata->irq_gpio, 0);
- usleep(RESET_DELAY_T3_US);
+ usleep_range(200, 250);
gpio_direction_output(ts->pdata->reset_gpio, 1);
msleep(RESET_DELAY_T4);
@@ -743,7 +745,7 @@ static u8 gtp_enter_sleep(struct goodix_ts_data *ts)
}
return 0;
}
- usleep(5000);
+ usleep_range(5000, 5500);
while (retry++ < GTP_I2C_RETRY_5) {
ret = gtp_i2c_write(ts->client, i2c_control_buf, 3);
if (ret == 1) {
@@ -812,7 +814,7 @@ err_retry:
} else {
ret = gpio_direction_output(
ts->pdata->irq_gpio, 1);
- usleep(5000);
+ usleep_range(5000, 5500);
}
}
ret = gtp_i2c_test(ts->client);
@@ -1174,11 +1176,10 @@ Output:
static int gtp_request_irq(struct goodix_ts_data *ts)
{
int ret = 0;
- const u8 irq_table[] = GTP_IRQ_TAB;
ret = request_threaded_irq(ts->client->irq, NULL,
goodix_ts_irq_handler,
- irq_table[ts->int_trigger_type],
+ ts->pdata->irq_gpio_flags,
ts->client->name, ts);
if (ret) {
ts->use_irq = false;
@@ -1459,7 +1460,7 @@ static int goodix_power_init(struct goodix_ts_data *ts)
"Regulator get failed vdd ret=%d\n", ret);
}
- ts->vcc_i2c = regulator_get(&ts->client->dev, "vcc-i2c");
+ ts->vcc_i2c = regulator_get(&ts->client->dev, "vcc_i2c");
if (IS_ERR(ts->vcc_i2c)) {
ret = PTR_ERR(ts->vcc_i2c);
dev_info(&ts->client->dev,
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.h b/drivers/input/touchscreen/gt9xx/gt9xx.h
index 028eb4babe0b..9cac7a33c33e 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.h
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.h
@@ -1,6 +1,6 @@
/* drivers/input/touchscreen/gt9xx.h
*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*
* Linux Foundation chooses to take subject only to the GPLv2 license
* terms, and distributes only under these terms.
@@ -116,7 +116,7 @@ extern u16 show_len;
extern u16 total_len;
/***************************PART1:ON/OFF define*******************************/
-#define GTP_CUSTOM_CFG 0
+#define GTP_CUSTOM_CFG 1
#define GTP_ESD_PROTECT 0
#define GTP_IRQ_TAB {\
@@ -130,7 +130,7 @@ extern u16 total_len;
#define GTP_IRQ_TAB_RISING 0
#define GTP_IRQ_TAB_FALLING 1
#if GTP_CUSTOM_CFG
-#define GTP_MAX_HEIGHT 800
+#define GTP_MAX_HEIGHT 864
#define GTP_MAX_WIDTH 480
#define GTP_INT_TRIGGER GTP_IRQ_TAB_RISING
#else
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx_update.c b/drivers/input/touchscreen/gt9xx/gt9xx_update.c
index 63f9c5c3ddfc..98f537b7a9b5 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx_update.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx_update.c
@@ -1,7 +1,7 @@
/* drivers/input/touchscreen/gt9xx_update.c
*
* 2010 - 2012 Goodix Technology.
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, 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 as published by
@@ -389,7 +389,7 @@ s32 gup_enter_update_mode(struct i2c_client *client)
/* step1:RST output low last at least 2ms */
gpio_direction_output(ts->pdata->reset_gpio, 0);
- usleep(20000);
+ msleep(20);
/* step2:select I2C slave addr,INT:0--0xBA;1--0x28. */
gpio_direction_output(ts->pdata->irq_gpio,
diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c
index f69539afe0b2..b2110f8b6032 100644
--- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c
+++ b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c
@@ -117,7 +117,6 @@
static int synaptics_rmi4_check_status(struct synaptics_rmi4_data *rmi4_data,
bool *was_in_bl_mode);
static int synaptics_rmi4_free_fingers(struct synaptics_rmi4_data *rmi4_data);
-static int synaptics_rmi4_reinit_device(struct synaptics_rmi4_data *rmi4_data);
static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data,
bool rebuild);
@@ -1686,12 +1685,6 @@ static void synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data,
}
if (status.unconfigured && !status.flash_prog) {
pr_notice("%s: spontaneous reset detected\n", __func__);
- retval = synaptics_rmi4_reinit_device(rmi4_data);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to reinit device\n",
- __func__);
- }
}
if (!report)
@@ -3660,49 +3653,6 @@ exit:
return;
}
-static int synaptics_rmi4_reinit_device(struct synaptics_rmi4_data *rmi4_data)
-{
- int retval;
- struct synaptics_rmi4_fn *fhandler;
- struct synaptics_rmi4_exp_fhandler *exp_fhandler;
- struct synaptics_rmi4_device_info *rmi;
-
- rmi = &(rmi4_data->rmi4_mod_info);
-
- mutex_lock(&(rmi4_data->rmi4_reset_mutex));
-
- synaptics_rmi4_free_fingers(rmi4_data);
-
- if (!list_empty(&rmi->support_fn_list)) {
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->fn_number == SYNAPTICS_RMI4_F12) {
- synaptics_rmi4_f12_set_enables(rmi4_data, 0);
- break;
- }
- }
- }
-
- retval = synaptics_rmi4_int_enable(rmi4_data, true);
- if (retval < 0)
- goto exit;
-
- mutex_lock(&exp_data.mutex);
- if (!list_empty(&exp_data.list)) {
- list_for_each_entry(exp_fhandler, &exp_data.list, link)
- if (exp_fhandler->exp_fn->reinit != NULL)
- exp_fhandler->exp_fn->reinit(rmi4_data);
- }
- mutex_unlock(&exp_data.mutex);
-
- synaptics_rmi4_set_configured(rmi4_data);
-
- retval = 0;
-
-exit:
- mutex_unlock(&(rmi4_data->rmi4_reset_mutex));
- return retval;
-}
-
static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data,
bool rebuild)
{
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 34c01065b578..30c4d968927b 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -129,6 +129,7 @@ static u64 __maybe_unused gic_read_iar(void)
asm volatile("mrs_s %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat));
/* As per the architecture specification */
+ isb();
mb();
return irqstat;
}
@@ -137,6 +138,7 @@ static void __maybe_unused gic_write_pmr(u64 val)
{
asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val));
/* As per the architecture specification */
+ isb();
mb();
}
@@ -156,6 +158,7 @@ static void __maybe_unused gic_write_sgi1r(u64 val)
{
asm volatile("msr_s " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val));
/* As per the architecture specification */
+ isb();
mb();
}
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 0c9962817849..06cad663be25 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -28,6 +28,10 @@ obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
obj-$(CONFIG_VIDEO_ADV7393) += adv7393.o
obj-$(CONFIG_VIDEO_ADV7604) += adv7604.o
obj-$(CONFIG_VIDEO_ADV7842) += adv7842.o
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/common
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci
obj-$(CONFIG_VIDEO_ADV7481) += adv7481.o
obj-$(CONFIG_VIDEO_AD9389B) += ad9389b.o
obj-$(CONFIG_VIDEO_ADV7511) += adv7511.o
diff --git a/drivers/media/i2c/adv7481.c b/drivers/media/i2c/adv7481.c
index 359a860fdabb..2ba8cb9623da 100644
--- a/drivers/media/i2c/adv7481.c
+++ b/drivers/media/i2c/adv7481.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016, 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
@@ -27,17 +27,27 @@
#include <media/v4l2-ctrls.h>
#include <linux/mutex.h>
#include <linux/delay.h>
+
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+
#include <media/adv7481.h>
#include <media/msm_ba.h>
#include "adv7481_reg.h"
+#include "msm_cci.h"
+#include "msm_camera_i2c.h"
+#include "msm_camera_io_util.h"
+#include "msm_camera_dt_util.h"
+
#define DRIVER_NAME "adv7481"
-#define I2C_RW_DELAY 100
-#define I2C_SW_RST_DELAY 10000
-#define GPIO_HW_DELAY_LOW 100000
-#define GPIO_HW_DELAY_HI 10000
+#define I2C_RW_DELAY 1
+#define I2C_SW_RST_DELAY 5000
+#define GPIO_HW_RST_DELAY_HI 10000
+#define GPIO_HW_RST_DELAY_LOW 10000
#define SDP_MIN_SLEEP 5000
#define SDP_MAX_SLEEP 6000
#define SDP_NUM_TRIES 30
@@ -45,11 +55,44 @@
#define LOCK_MAX_SLEEP 6000
#define LOCK_NUM_TRIES 20
+#define MAX_DEFAULT_WIDTH 1280
+#define MAX_DEFAULT_HEIGHT 720
+#define MAX_DEFAULT_FRAME_RATE 60
+#define MAX_DEFAULT_PIX_CLK_HZ 74240000
+
#define ONE_MHZ_TO_HZ 1000000
+enum adv7481_gpio_t {
+
+ CCI_I2C_SDA = 0,
+ CCI_I2C_SCL,
+
+ ADV7481_GPIO_RST,
+
+ ADV7481_GPIO_INT1,
+ ADV7481_GPIO_INT2,
+ ADV7481_GPIO_INT3,
+
+ ADV7481_GPIO_MAX,
+};
+
struct adv7481_state {
/* Platform Data */
struct adv7481_platform_data pdata;
+ struct device *dev;
+
+ /* VREG */
+ struct camera_vreg_t *cci_vreg;
+ struct regulator *cci_reg_ptr[MAX_REGULATOR];
+ int32_t regulator_count;
+
+ /* I2C */
+ struct msm_camera_i2c_client i2c_client;
+ u32 cci_master;
+ u32 i2c_slave_addr;
+ u32 i2c_csi_slave_addr;
+ u32 i2c_vpp_slave_addr;
+ u32 register_page;
/* V4L2 Data */
struct v4l2_subdev sd;
@@ -63,19 +106,24 @@ struct adv7481_state {
struct workqueue_struct *work_queues;
struct mutex mutex;
- struct i2c_client *client;
- struct i2c_client *i2c_csi_txa;
- struct i2c_client *i2c_csi_txb;
- struct i2c_client *i2c_hdmi;
- struct i2c_client *i2c_edid;
- struct i2c_client *i2c_cp;
- struct i2c_client *i2c_sdp;
- struct i2c_client *i2c_rep;
+ uint8_t i2c_io_addr;
+ uint8_t i2c_csi_txa_addr;
+ uint8_t i2c_csi_txb_addr;
+ uint8_t i2c_hdmi_addr;
+ uint8_t i2c_edid_addr;
+ uint8_t i2c_cp_addr;
+ uint8_t i2c_sdp_addr;
+ uint8_t i2c_rep_addr;
+ uint8_t i2c_cbus_addr;
/* device status and Flags */
int irq;
int device_num;
int powerup;
+ int cec_detected;
+
+ /* GPIOs */
+ struct gpio gpio_array[ADV7481_GPIO_MAX];
/* routing configuration data */
int csia_src;
@@ -196,6 +244,9 @@ const uint8_t adv7481_default_edid_data[] = {
#define ADV7481_EDID_SIZE ARRAY_SIZE(adv7481_default_edid_data)
+static u32 adv7481_inp_to_ba(u32 adv_input);
+static bool adv7481_is_timing_locked(struct adv7481_state *state);
+
static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
{
return &(container_of(ctrl->handler,
@@ -208,50 +259,102 @@ static inline struct adv7481_state *to_state(struct v4l2_subdev *sd)
}
/* I2C Rd/Rw Functions */
-static int adv7481_wr_byte(struct i2c_client *i2c_client, unsigned int reg,
- unsigned int value)
+static int32_t adv7481_cci_i2c_write(struct msm_camera_i2c_client *i2c_client,
+ uint8_t reg, uint16_t *data,
+ enum msm_camera_i2c_data_type data_type)
{
- int ret;
+ return i2c_client->i2c_func_tbl->i2c_write(i2c_client, reg,
+ *data, data_type);
+}
+
+static int32_t adv7481_cci_i2c_read(struct msm_camera_i2c_client *i2c_client,
+ uint8_t reg, uint16_t *data,
+ enum msm_camera_i2c_data_type data_type)
+{
+ return i2c_client->i2c_func_tbl->i2c_read(i2c_client, reg,
+ data, data_type);
+}
+
+static int32_t adv7481_wr_byte(struct msm_camera_i2c_client *c_i2c_client,
+ uint8_t sid, uint8_t reg, uint8_t data)
+{
+ uint16_t write_data = data;
+ int ret = 0;
+
+ c_i2c_client->cci_client->sid = sid;
- ret = i2c_smbus_write_byte_data(i2c_client, reg & 0xFF, value);
- usleep_range(I2C_RW_DELAY, 2*I2C_RW_DELAY);
+ ret = adv7481_cci_i2c_write(c_i2c_client, reg, &write_data,
+ MSM_CAMERA_I2C_BYTE_DATA);
+ if (ret < 0)
+ pr_err("Error %d writing cci i2c\n", ret);
return ret;
}
-static int adv7481_rd_byte(struct i2c_client *i2c_client, unsigned int reg)
+static uint8_t adv7481_rd_byte(struct msm_camera_i2c_client *c_i2c_client,
+ uint8_t sid, uint8_t reg)
{
+ uint16_t data = 0;
+ int ret = 0;
+
+ c_i2c_client->cci_client->sid = sid;
+ ret = adv7481_cci_i2c_read(c_i2c_client, reg, &data,
+ MSM_CAMERA_I2C_BYTE_DATA);
+ if (ret < 0) {
+ pr_err("Error %d reading cci i2c\n", ret);
+ return ret;
+ }
+
+ return (uint8_t)(data & 0xFF);
+}
+
+static uint16_t adv7481_rd_word(struct msm_camera_i2c_client *c_i2c_client,
+ uint8_t sid, uint8_t reg)
+{
+ uint16_t data = 0;
int ret;
- ret = i2c_smbus_read_byte_data(i2c_client, reg & 0xFF);
- usleep_range(I2C_RW_DELAY, 2*I2C_RW_DELAY);
+ c_i2c_client->cci_client->sid = sid;
+ ret = adv7481_cci_i2c_read(c_i2c_client, reg, &data,
+ MSM_CAMERA_I2C_WORD_DATA);
+ if (ret < 0) {
+ pr_err("Error %d reading cci i2c\n", ret);
+ return ret;
+ }
- return ret;
+ return data;
}
static int adv7481_set_irq(struct adv7481_state *state)
{
int ret = 0;
- ret = adv7481_wr_byte(state->client, IO_REG_PAD_CTRL_1_ADDR,
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_PAD_CTRL_1_ADDR,
ADV_REG_SETFIELD(1, IO_PDN_INT2) |
ADV_REG_SETFIELD(1, IO_PDN_INT3) |
ADV_REG_SETFIELD(1, IO_INV_LLC) |
ADV_REG_SETFIELD(AD_MID_DRIVE_STRNGTH, IO_DRV_LLC_PAD));
- ret |= adv7481_wr_byte(state->client, IO_REG_INT1_CONF_ADDR,
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_INT1_CONF_ADDR,
ADV_REG_SETFIELD(AD_ACTIVE_UNTIL_CLR,
IO_INTRQ_DUR_SEL) |
ADV_REG_SETFIELD(AD_OP_DRIVE_LOW, IO_INTRQ_OP_SEL));
- ret |= adv7481_wr_byte(state->client, IO_REG_INT2_CONF_ADDR,
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_INT2_CONF_ADDR,
ADV_REG_SETFIELD(1, IO_CP_LOCK_UNLOCK_EDGE_SEL));
- ret |= adv7481_wr_byte(state->client, IO_REG_DATAPATH_INT_MASKB_ADDR,
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_DATAPATH_INT_MASKB_ADDR,
ADV_REG_SETFIELD(1, IO_CP_LOCK_CP_MB1) |
ADV_REG_SETFIELD(1, IO_CP_UNLOCK_CP_MB1) |
ADV_REG_SETFIELD(1, IO_VMUTE_REQUEST_HDMI_MB1) |
ADV_REG_SETFIELD(1, IO_INT_SD_MB1));
- /* Set hpa */
- ret |= adv7481_wr_byte(state->client, IO_HDMI_LVL_INT_MASKB_3_ADDR,
- ADV_REG_SETFIELD(1, IO_CABLE_DET_A_MB1));
+ /* Set cable detect */
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_HDMI_LVL_INT_MASKB_3_ADDR,
+ ADV_REG_SETFIELD(1, IO_CABLE_DET_A_MB1) |
+ ADV_REG_SETFIELD(1, IO_V_LOCKED_MB1) |
+ ADV_REG_SETFIELD(1, IO_DE_REGEN_LCK_MB1));
if (ret)
pr_err("%s: Failed %d to setup interrupt regs\n",
@@ -262,6 +365,20 @@ static int adv7481_set_irq(struct adv7481_state *state)
return ret;
}
+static int adv7481_reset_irq(struct adv7481_state *state)
+{
+ int ret = 0;
+
+ disable_irq(state->irq);
+
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_DATAPATH_INT_MASKB_ADDR, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_HDMI_LVL_INT_MASKB_3_ADDR, 0x00);
+
+ return ret;
+}
+
static int adv7481_set_edid(struct adv7481_state *state)
{
int i;
@@ -269,24 +386,27 @@ static int adv7481_set_edid(struct adv7481_state *state)
uint8_t edid_state;
/* Enable Manual Control of EDID on Port A */
- ret |= adv7481_wr_byte(state->i2c_rep, 0x74, 0x01);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_rep_addr, 0x74,
+ 0x01);
/* Disable Auto Enable of EDID */
- ret |= adv7481_wr_byte(state->i2c_rep, 0x7A, 0x08);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_rep_addr, 0x7A,
+ 0x08);
/* Set Primary EDID Size to 256 Bytes */
- ret |= adv7481_wr_byte(state->i2c_rep, 0x70, 0x20);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_rep_addr, 0x70,
+ 0x20);
/*
* Readback EDID enable state after a combination of manual
* and automatic functions
*/
- edid_state = adv7481_rd_byte(state->i2c_rep,
+ edid_state = adv7481_rd_byte(&state->i2c_client, state->i2c_rep_addr,
HDMI_REG_RO_EDID_DEBUG_2_ADDR);
pr_debug("%s: Readback EDID enable state: 0x%x\n", __func__,
edid_state);
for (i = 0; i < ADV7481_EDID_SIZE; i++) {
- ret |= adv7481_wr_byte(state->i2c_edid, i,
- adv7481_default_edid_data[i]);
+ ret |= adv7481_wr_byte(&state->i2c_client,
+ state->i2c_edid_addr, i, adv7481_default_edid_data[i]);
}
return ret;
@@ -304,43 +424,131 @@ static irqreturn_t adv7481_irq(int irq, void *dev)
static void adv7481_irq_delay_work(struct work_struct *work)
{
struct adv7481_state *state;
- uint8_t status;
+ uint8_t int_raw_status;
+ uint8_t int_status;
+ uint8_t raw_status;
state = container_of(work, struct adv7481_state,
irq_delayed_work.work);
mutex_lock(&state->mutex);
- /* workaround for irq trigger */
- status = adv7481_rd_byte(state->client,
+ /* Read raw irq status register */
+ int_raw_status = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
IO_REG_INT_RAW_STATUS_ADDR);
pr_debug("%s: dev: %d got int raw status: 0x%x\n", __func__,
- state->device_num, status);
-
- status = adv7481_rd_byte(state->client,
- IO_REG_DATAPATH_INT_STATUS_ADDR);
-
- pr_debug("%s: dev: %d got datapath int status: 0x%x\n", __func__,
- state->device_num, status);
+ state->device_num, int_raw_status);
+ state->cec_detected = ADV_REG_GETFIELD(int_raw_status, IO_INT_CEC_ST);
+
+ if (ADV_REG_GETFIELD(int_raw_status, IO_INTRQ1_RAW)) {
+ int lock_status = -1;
+ struct v4l2_event event = {0};
+ int *ptr = (int *)event.u.data;
+
+ pr_debug("%s: dev: %d got intrq1_raw\n", __func__,
+ state->device_num);
+ int_status = adv7481_rd_byte(&state->i2c_client,
+ state->i2c_io_addr,
+ IO_REG_DATAPATH_INT_STATUS_ADDR);
+
+ raw_status = adv7481_rd_byte(&state->i2c_client,
+ state->i2c_io_addr,
+ IO_REG_DATAPATH_RAW_STATUS_ADDR);
+
+ adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_DATAPATH_INT_CLEAR_ADDR, int_status);
+
+ pr_debug("%s: dev: %d got datapath int status: 0x%x\n",
+ __func__, state->device_num, int_status);
+
+ pr_debug("%s: dev: %d got datapath raw status: 0x%x\n",
+ __func__, state->device_num, raw_status);
+
+ if (ADV_REG_GETFIELD(int_status, IO_CP_LOCK_CP_ST) &&
+ ADV_REG_GETFIELD(raw_status, IO_CP_LOCK_CP_RAW)) {
+ lock_status = 0;
+ pr_debug(
+ "%s: set lock_status IO_CP_LOCK_CP_RAW: 0x%x\n",
+ __func__, lock_status);
+ }
+ if (ADV_REG_GETFIELD(int_status, IO_CP_UNLOCK_CP_ST) &&
+ ADV_REG_GETFIELD(raw_status, IO_CP_UNLOCK_CP_RAW)) {
+ lock_status = 1;
+ pr_debug(
+ "%s: set lock_status IO_CP_UNLOCK_CP_RAW: 0x%x\n",
+ __func__, lock_status);
+ }
+ if (lock_status >= 0) {
+ ptr[0] = adv7481_inp_to_ba(state->mode);
+ ptr[1] = lock_status;
+ event.type = lock_status ?
+ V4L2_EVENT_MSM_BA_SIGNAL_LOST_LOCK :
+ V4L2_EVENT_MSM_BA_SIGNAL_IN_LOCK;
+ v4l2_subdev_notify(&state->sd,
+ event.type, &event);
+ }
+ }
- adv7481_wr_byte(state->client,
- IO_REG_DATAPATH_INT_CLEAR_ADDR, status);
+ if (ADV_REG_GETFIELD(int_raw_status, IO_INT_HDMI_ST)) {
+ int cable_detected = 0;
+ struct v4l2_event event = {0};
+ int *ptr = (int *)event.u.data;
- status = adv7481_rd_byte(state->client,
- IO_REG_DATAPATH_RAW_STATUS_ADDR);
+ ptr[0] = adv7481_inp_to_ba(state->mode);
- pr_debug("%s: dev: %d got datapath rawstatus: 0x%x\n", __func__,
- state->device_num, status);
+ pr_debug("%s: dev: %d got int_hdmi_st\n", __func__,
+ state->device_num);
- status = adv7481_rd_byte(state->client,
- IO_HDMI_LVL_INT_STATUS_3_ADDR);
+ int_status = adv7481_rd_byte(&state->i2c_client,
+ state->i2c_io_addr,
+ IO_HDMI_LVL_INT_STATUS_3_ADDR);
- pr_debug("%s: dev: %d got hdmi lvl int status 3: 0x%x\n", __func__,
- state->device_num, status);
+ raw_status = adv7481_rd_byte(&state->i2c_client,
+ state->i2c_io_addr,
+ IO_HDMI_LVL_RAW_STATUS_3_ADDR);
- adv7481_wr_byte(state->client,
- IO_HDMI_LVL_INT_CLEAR_3_ADDR, status);
+ pr_debug("%s: dev: %d got hdmi lvl int status 3: 0x%x\n",
+ __func__, state->device_num, int_status);
+ pr_debug("%s: dev: %d got hdmi lvl raw status 3: 0x%x\n",
+ __func__, state->device_num, raw_status);
+
+
+ if (ADV_REG_GETFIELD(int_status, IO_CABLE_DET_A_ST)) {
+ cable_detected = ADV_REG_GETFIELD(raw_status,
+ IO_CABLE_DET_A_RAW);
+ pr_debug("%s: set cable_detected: 0x%x\n",
+ __func__, cable_detected);
+ ptr[1] = cable_detected;
+ event.type = V4L2_EVENT_MSM_BA_CABLE_DETECT;
+ v4l2_subdev_notify(&state->sd,
+ event.type, &event);
+ }
+ /* Assumption is that vertical sync int
+ * is the last one to come */
+ if (ADV_REG_GETFIELD(int_status, IO_V_LOCKED_ST)) {
+ if (ADV_REG_GETFIELD(raw_status,
+ IO_TMDSPLL_LCK_A_RAW) &&
+ ADV_REG_GETFIELD(raw_status,
+ IO_V_LOCKED_RAW) &&
+ ADV_REG_GETFIELD(raw_status,
+ IO_DE_REGEN_LCK_RAW)) {
+ pr_debug("%s: port settings changed\n",
+ __func__);
+ event.type =
+ V4L2_EVENT_MSM_BA_PORT_SETTINGS_CHANGED;
+ v4l2_subdev_notify(&state->sd,
+ event.type, &event);
+ }
+ }
+ }
+ /* Clear all other interrupts */
+ adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_HDMI_LVL_INT_CLEAR_1_ADDR, 0xFF);
+ adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_HDMI_LVL_INT_CLEAR_2_ADDR, 0xFF);
+ adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_HDMI_LVL_INT_CLEAR_3_ADDR, 0xFF);
mutex_unlock(&state->mutex);
}
@@ -350,110 +558,100 @@ static int adv7481_cec_wakeup(struct adv7481_state *state, bool enable)
uint8_t val;
int ret = 0;
- val = adv7481_rd_byte(state->client,
+ val = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
IO_REG_PWR_DN2_XTAL_HIGH_ADDR);
val = ADV_REG_GETFIELD(val, IO_PROG_XTAL_FREQ_HIGH);
if (enable) {
/* CEC wake up enabled in power-down mode */
val |= ADV_REG_SETFIELD(1, IO_CTRL_CEC_WAKE_UP_PWRDN2B) |
ADV_REG_SETFIELD(0, IO_CTRL_CEC_WAKE_UP_PWRDNB);
- ret = adv7481_wr_byte(state->client,
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
IO_REG_PWR_DN2_XTAL_HIGH_ADDR, val);
} else {
/* CEC wake up disabled in power-down mode */
val |= ADV_REG_SETFIELD(0, IO_CTRL_CEC_WAKE_UP_PWRDN2B) |
ADV_REG_SETFIELD(1, IO_CTRL_CEC_WAKE_UP_PWRDNB);
- ret = adv7481_wr_byte(state->client,
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
IO_REG_PWR_DN2_XTAL_HIGH_ADDR, val);
}
return ret;
}
/* Initialize adv7481 I2C Settings */
-static int adv7481_dev_init(struct adv7481_state *state,
- struct i2c_client *client)
+static int adv7481_dev_init(struct adv7481_state *state)
{
+ uint16_t chip_rev_id;
int ret;
mutex_lock(&state->mutex);
/* Soft reset */
- ret = adv7481_wr_byte(state->client,
- IO_REG_MAIN_RST_ADDR, IO_REG_MAIN_RST_VALUE);
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_MAIN_RST_ADDR, IO_REG_MAIN_RST_VALUE);
/* Delay required following I2C reset and I2C transactions */
- usleep_range(I2C_SW_RST_DELAY, I2C_SW_RST_DELAY+1000);
+ usleep_range(I2C_SW_RST_DELAY, I2C_SW_RST_DELAY + 1000);
+
+ chip_rev_id = adv7481_rd_word(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_CHIP_REV_ID_1_ADDR);
+ pr_debug("%s: ADV7481 chip rev id: 0x%x", __func__, chip_rev_id);
/* Disable CEC wake up in power-down mode */
ret |= adv7481_cec_wakeup(state, 0);
/* Setting Vid_Std to 720x480p60 */
- ret |= adv7481_wr_byte(state->client,
- IO_REG_CP_VID_STD_ADDR, 0x4A);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_CP_VID_STD_ADDR, 0x4A);
/* Configure I2C Maps and I2C Communication Settings */
/* io_reg_f2 I2C Auto Increment */
- ret |= adv7481_wr_byte(state->client, IO_REG_I2C_CFG_ADDR,
- IO_REG_I2C_AUTOINC_EN_REG_VALUE);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_I2C_CFG_ADDR, IO_REG_I2C_AUTOINC_EN_REG_VALUE);
/* DPLL Map Address */
- ret |= adv7481_wr_byte(state->client, IO_REG_DPLL_ADDR,
- IO_REG_DPLL_SADDR);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_DPLL_ADDR, IO_REG_DPLL_SADDR);
/* CP Map Address */
- ret |= adv7481_wr_byte(state->client, IO_REG_CP_ADDR,
- IO_REG_CP_SADDR);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_CP_ADDR, IO_REG_CP_SADDR);
/* HDMI RX Map Address */
- ret |= adv7481_wr_byte(state->client, IO_REG_HDMI_ADDR,
- IO_REG_HDMI_SADDR);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_HDMI_ADDR, IO_REG_HDMI_SADDR);
/* EDID Map Address */
- ret |= adv7481_wr_byte(state->client, IO_REG_EDID_ADDR,
- IO_REG_EDID_SADDR);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_EDID_ADDR, IO_REG_EDID_SADDR);
/* HDMI RX Repeater Map Address */
- ret |= adv7481_wr_byte(state->client, IO_REG_HDMI_REP_ADDR,
- IO_REG_HDMI_REP_SADDR);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_HDMI_REP_ADDR, IO_REG_HDMI_REP_SADDR);
/* HDMI RX Info-frame Map Address */
- ret |= adv7481_wr_byte(state->client, IO_REG_HDMI_INF_ADDR,
- IO_REG_HDMI_INF_SADDR);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_HDMI_INF_ADDR, IO_REG_HDMI_INF_SADDR);
/* CBUS Map Address */
- ret |= adv7481_wr_byte(state->client, IO_REG_CBUS_ADDR,
- IO_REG_CBUS_SADDR);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_CBUS_ADDR, IO_REG_CBUS_SADDR);
/* CEC Map Address */
- ret |= adv7481_wr_byte(state->client, IO_REG_CEC_ADDR,
- IO_REG_CEC_SADDR);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_CEC_ADDR, IO_REG_CEC_SADDR);
/* SDP Main Map Address */
- ret |= adv7481_wr_byte(state->client, IO_REG_SDP_ADDR,
- IO_REG_SDP_SADDR);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_SDP_ADDR, IO_REG_SDP_SADDR);
/* CSI-TXB Map Address */
- ret |= adv7481_wr_byte(state->client, IO_REG_CSI_TXB_ADDR,
- IO_REG_CSI_TXB_SADDR);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_CSI_TXB_ADDR, IO_REG_CSI_TXB_SADDR);
/* CSI-TXA Map Address */
- ret |= adv7481_wr_byte(state->client, IO_REG_CSI_TXA_ADDR,
- IO_REG_CSI_TXA_SADDR);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_CSI_TXA_ADDR, IO_REG_CSI_TXA_SADDR);
if (ret) {
pr_err("%s: Failed dev init %d\n", __func__, ret);
goto err_exit;
}
/* Configure i2c clients */
- state->i2c_csi_txa = i2c_new_dummy(client->adapter,
- IO_REG_CSI_TXA_SADDR >> 1);
- state->i2c_csi_txb = i2c_new_dummy(client->adapter,
- IO_REG_CSI_TXB_SADDR >> 1);
- state->i2c_cp = i2c_new_dummy(client->adapter,
- IO_REG_CP_SADDR >> 1);
- state->i2c_hdmi = i2c_new_dummy(client->adapter,
- IO_REG_HDMI_SADDR >> 1);
- state->i2c_edid = i2c_new_dummy(client->adapter,
- IO_REG_EDID_SADDR >> 1);
- state->i2c_sdp = i2c_new_dummy(client->adapter,
- IO_REG_SDP_SADDR >> 1);
- state->i2c_rep = i2c_new_dummy(client->adapter,
- IO_REG_HDMI_REP_SADDR >> 1);
-
- if (!state->i2c_csi_txa || !state->i2c_csi_txb || !state->i2c_cp ||
- !state->i2c_sdp || !state->i2c_hdmi || !state->i2c_edid ||
- !state->i2c_rep) {
- pr_err("%s: Additional I2C Client Fail\n", __func__);
- ret = -EFAULT;
- goto err_exit;
- }
+ state->i2c_csi_txa_addr = IO_REG_CSI_TXA_SADDR >> 1;
+ state->i2c_csi_txb_addr = IO_REG_CSI_TXB_SADDR >> 1;
+ state->i2c_cp_addr = IO_REG_CP_SADDR >> 1;
+ state->i2c_hdmi_addr = IO_REG_HDMI_SADDR >> 1;
+ state->i2c_edid_addr = IO_REG_EDID_SADDR >> 1;
+ state->i2c_sdp_addr = IO_REG_SDP_SADDR >> 1;
+ state->i2c_rep_addr = IO_REG_HDMI_REP_SADDR >> 1;
+ state->i2c_cbus_addr = IO_REG_CBUS_SADDR >> 1;
ret = adv7481_set_edid(state);
ret |= adv7481_set_irq(state);
@@ -465,28 +663,27 @@ err_exit:
}
/* Initialize adv7481 hardware */
-static int adv7481_hw_init(struct adv7481_platform_data *pdata,
- struct adv7481_state *state)
+static int adv7481_hw_init(struct adv7481_state *state)
{
int ret = 0;
- if (!pdata) {
- pr_err("%s: PDATA is NULL\n", __func__);
- return -EFAULT;
- }
-
mutex_lock(&state->mutex);
- if (gpio_is_valid(pdata->rstb_gpio)) {
- ret = gpio_request(pdata->rstb_gpio, "rstb_gpio");
- if (ret) {
- pr_err("%s: Request GPIO Fail %d\n", __func__, ret);
- goto err_exit;
- }
- ret = gpio_direction_output(pdata->rstb_gpio, 0);
- usleep_range(GPIO_HW_DELAY_LOW, GPIO_HW_DELAY_LOW+1000);
- ret = gpio_direction_output(pdata->rstb_gpio, 1);
- usleep_range(GPIO_HW_DELAY_HI, GPIO_HW_DELAY_HI+1000);
+ /* Bring ADV7481 out of reset */
+ ret = gpio_request_array(&state->gpio_array[ADV7481_GPIO_RST], 1);
+ if (ret < 0) {
+ pr_err("%s: Failed to request reset GPIO %d\n", __func__, ret);
+ goto err_exit;
+ }
+ if (gpio_is_valid(state->gpio_array[ADV7481_GPIO_RST].gpio)) {
+ ret |= gpio_direction_output(
+ state->gpio_array[ADV7481_GPIO_RST].gpio, 0);
+ usleep_range(GPIO_HW_RST_DELAY_LOW, GPIO_HW_RST_DELAY_LOW +
+ 1000);
+ ret |= gpio_direction_output(
+ state->gpio_array[ADV7481_GPIO_RST].gpio, 1);
+ usleep_range(GPIO_HW_RST_DELAY_HI, GPIO_HW_RST_DELAY_HI +
+ 1000);
if (ret) {
pr_err("%s: Set GPIO Fail %d\n", __func__, ret);
goto err_exit;
@@ -494,22 +691,21 @@ static int adv7481_hw_init(struct adv7481_platform_data *pdata,
}
/* Only setup IRQ1 for now... */
- if (gpio_is_valid(pdata->irq1_gpio)) {
- ret = gpio_request(pdata->irq1_gpio, "irq_gpio");
- if (ret) {
- pr_err("%s: Failed to request irq_gpio %d\n",
- __func__, ret);
- goto err_exit;
- }
-
- ret = gpio_direction_input(pdata->irq1_gpio);
+ ret = gpio_request_array(&state->gpio_array[ADV7481_GPIO_INT1], 1);
+ if (ret < 0) {
+ pr_err("%s: Failed to request irq_gpio %d\n", __func__, ret);
+ goto err_exit;
+ }
+ if (gpio_is_valid(state->gpio_array[ADV7481_GPIO_INT1].gpio)) {
+ ret |= gpio_direction_input(
+ state->gpio_array[ADV7481_GPIO_INT1].gpio);
if (ret) {
pr_err("%s: Failed gpio_direction irq %d\n",
__func__, ret);
goto err_exit;
}
-
- state->irq = gpio_to_irq(pdata->irq1_gpio);
+ state->irq = gpio_to_irq(
+ state->gpio_array[ADV7481_GPIO_INT1].gpio);
if (state->irq) {
ret = request_irq(state->irq, adv7481_irq,
IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
@@ -519,18 +715,16 @@ static int adv7481_hw_init(struct adv7481_platform_data *pdata,
__func__, ret);
goto err_exit;
}
+ /* disable irq until chip interrupts are programmed */
+ disable_irq(state->irq);
} else {
pr_err("%s: Failed gpio_to_irq %d\n", __func__, ret);
ret = -EINVAL;
goto err_exit;
}
-
- /* disable irq until chip interrupts are programmed */
- disable_irq(state->irq);
-
- INIT_DELAYED_WORK(&state->irq_delayed_work,
- adv7481_irq_delay_work);
}
+ INIT_DELAYED_WORK(&state->irq_delayed_work,
+ adv7481_irq_delay_work);
err_exit:
mutex_unlock(&state->mutex);
@@ -548,31 +742,40 @@ static int adv7481_s_ctrl(struct v4l2_ctrl *ctrl)
pr_debug("Enter %s: id = 0x%x\n", __func__, ctrl->id);
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
- temp = adv7481_rd_byte(state->client, CP_REG_VID_ADJ);
+ temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_VID_ADJ);
temp |= CP_CTR_VID_ADJ_EN;
- ret = adv7481_wr_byte(state->client, CP_REG_VID_ADJ, temp);
- ret |= adv7481_wr_byte(state->client,
- CP_REG_BRIGHTNESS, ctrl->val);
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_VID_ADJ, temp);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_BRIGHTNESS, ctrl->val);
break;
case V4L2_CID_CONTRAST:
- temp = adv7481_rd_byte(state->client, CP_REG_VID_ADJ);
+ temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_VID_ADJ);
temp |= CP_CTR_VID_ADJ_EN;
- ret = adv7481_wr_byte(state->client, CP_REG_VID_ADJ, temp);
- ret |= adv7481_wr_byte(state->client,
- CP_REG_CONTRAST, ctrl->val);
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_VID_ADJ, temp);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_CONTRAST, ctrl->val);
break;
case V4L2_CID_SATURATION:
- temp = adv7481_rd_byte(state->client, CP_REG_VID_ADJ);
+ temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_VID_ADJ);
temp |= CP_CTR_VID_ADJ_EN;
- ret = adv7481_wr_byte(state->client, CP_REG_VID_ADJ, temp);
- ret |= adv7481_wr_byte(state->client,
- CP_REG_SATURATION, ctrl->val);
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_VID_ADJ, temp);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_SATURATION, ctrl->val);
break;
case V4L2_CID_HUE:
- temp = adv7481_rd_byte(state->client, CP_REG_VID_ADJ);
+ temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_VID_ADJ);
temp |= CP_CTR_VID_ADJ_EN;
- ret = adv7481_wr_byte(state->client, CP_REG_VID_ADJ, temp);
- ret |= adv7481_wr_byte(state->client, CP_REG_HUE, ctrl->val);
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_VID_ADJ, temp);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CP_REG_HUE, ctrl->val);
break;
default:
break;
@@ -611,6 +814,108 @@ static int adv7481_s_power(struct v4l2_subdev *sd, int on)
return ret;
}
+static int adv7481_set_cec_logical_addr(struct adv7481_state *state, int *la)
+{
+ int rc = 0;
+ uint8_t val;
+
+ if (!la) {
+ pr_err("%s: NULL pointer provided\n", __func__);
+ return -EINVAL;
+ }
+
+ val = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
+ CEC_REG_LOG_ADDR_MASK_ADDR);
+ if (ADV_REG_GETFIELD(val, CEC_REG_LOG_ADDR_MASK0)) {
+ val = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
+ CEC_REG_LOGICAL_ADDRESS0_1_ADDR);
+ val = ADV_REG_RSTFIELD(val, CEC_REG_LOGICAL_ADDRESS0);
+ val |= ADV_REG_SETFIELD(*la, CEC_REG_LOGICAL_ADDRESS0);
+ rc = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CEC_REG_LOGICAL_ADDRESS0_1_ADDR, val);
+ } else if (ADV_REG_GETFIELD(val, CEC_REG_LOG_ADDR_MASK1)) {
+ val = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
+ CEC_REG_LOGICAL_ADDRESS0_1_ADDR);
+ val = ADV_REG_RSTFIELD(val, CEC_REG_LOGICAL_ADDRESS1);
+ val |= ADV_REG_SETFIELD(*la, CEC_REG_LOGICAL_ADDRESS1);
+ rc = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CEC_REG_LOGICAL_ADDRESS0_1_ADDR, val);
+ } else if (ADV_REG_GETFIELD(val, CEC_REG_LOG_ADDR_MASK2)) {
+ val = ADV_REG_SETFIELD(*la, CEC_REG_LOGICAL_ADDRESS2);
+ rc = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CEC_REG_LOGICAL_ADDRESS2_ADDR, val);
+ } else {
+ pr_err("No cec logical address mask set\n");
+ }
+
+ return rc;
+}
+
+static int adv7481_cec_powerup(struct adv7481_state *state, int *powerup)
+{
+ int rc = 0;
+ uint8_t val = 0;
+
+ if (!powerup) {
+ pr_err("%s: NULL pointer provided\n", __func__);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: set power %d\n", __func__, *powerup);
+
+ val = ADV_REG_SETFIELD(*powerup, CEC_REG_CEC_POWER_UP);
+ rc = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ CEC_REG_CEC_POWER_UP_ADDR, val);
+
+ return rc;
+}
+
+static long adv7481_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+ struct adv7481_state *state = to_state(sd);
+ int *ret_val = arg;
+ long ret = 0;
+ int param = 0;
+
+ pr_debug("Enter %s with command: 0x%x", __func__, cmd);
+
+ if (!sd)
+ return -EINVAL;
+
+ switch (cmd) {
+ case VIDIOC_HDMI_RX_CEC_S_LOGICAL:
+ ret = adv7481_set_cec_logical_addr(state, arg);
+ break;
+ case VIDIOC_HDMI_RX_CEC_CLEAR_LOGICAL:
+ ret = adv7481_set_cec_logical_addr(state, &param);
+ break;
+ case VIDIOC_HDMI_RX_CEC_G_PHYSICAL:
+ if (ret_val) {
+ *ret_val = 0;
+ } else {
+ pr_err("%s: NULL pointer provided\n", __func__);
+ ret = -EINVAL;
+ }
+ break;
+ case VIDIOC_HDMI_RX_CEC_G_CONNECTED:
+ if (ret_val) {
+ *ret_val = state->cec_detected;
+ } else {
+ pr_err("%s: NULL pointer provided\n", __func__);
+ ret = -EINVAL;
+ }
+ break;
+ case VIDIOC_HDMI_RX_CEC_S_ENABLE:
+ ret = adv7481_cec_powerup(state, arg);
+ break;
+ default:
+ pr_err("Not a typewriter! Command: 0x%x", cmd);
+ ret = -ENOTTY;
+ break;
+ }
+ return ret;
+}
+
static int adv7481_get_sd_timings(struct adv7481_state *state, int *sd_standard)
{
int ret = 0;
@@ -621,17 +926,16 @@ static int adv7481_get_sd_timings(struct adv7481_state *state, int *sd_standard)
return -EINVAL;
do {
- sdp_stat = adv7481_rd_byte(state->i2c_sdp,
- SDP_RO_MAIN_STATUS1_ADDR);
+ sdp_stat = adv7481_rd_byte(&state->i2c_client,
+ state->i2c_sdp_addr, SDP_RO_MAIN_STATUS1_ADDR);
usleep_range(SDP_MIN_SLEEP, SDP_MAX_SLEEP);
timeout++;
- sdp_stat2 = adv7481_rd_byte(state->i2c_sdp,
- SDP_RO_MAIN_STATUS1_ADDR);
+ sdp_stat2 = adv7481_rd_byte(&state->i2c_client,
+ state->i2c_sdp_addr, SDP_RO_MAIN_STATUS1_ADDR);
} while ((sdp_stat != sdp_stat2) && (timeout < SDP_NUM_TRIES));
if (sdp_stat != sdp_stat2) {
- pr_err("%s(%d), adv7481 SDP status unstable: 1\n",
- __func__, __LINE__);
+ pr_err("%s, adv7481 SDP status unstable: 1\n", __func__);
return -ETIMEDOUT;
}
@@ -681,22 +985,35 @@ static int adv7481_set_cvbs_mode(struct adv7481_state *state)
pr_debug("Enter %s\n", __func__);
state->mode = ADV7481_IP_CVBS_1;
/* cvbs video settings ntsc etc */
- ret = adv7481_wr_byte(state->client, 0x00, 0x30);
- ret |= adv7481_wr_byte(state->i2c_sdp, 0x0f, 0x00);
- ret |= adv7481_wr_byte(state->i2c_sdp, 0x00, 0x00);
- ret |= adv7481_wr_byte(state->i2c_sdp, 0x03, 0x42);
- ret |= adv7481_wr_byte(state->i2c_sdp, 0x04, 0x07);
- ret |= adv7481_wr_byte(state->i2c_sdp, 0x13, 0x00);
- ret |= adv7481_wr_byte(state->i2c_sdp, 0x17, 0x41);
- ret |= adv7481_wr_byte(state->i2c_sdp, 0x31, 0x12);
- ret |= adv7481_wr_byte(state->i2c_sdp, 0x52, 0xcd);
- ret |= adv7481_wr_byte(state->i2c_sdp, 0x0e, 0xff);
- val = adv7481_rd_byte(state->client, IO_REG_CSI_PIX_EN_SEL_ADDR);
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ 0x00, 0x30);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr,
+ 0x0f, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr,
+ 0x00, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr,
+ 0x03, 0x42);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr,
+ 0x04, 0x07);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr,
+ 0x13, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr,
+ 0x17, 0x41);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr,
+ 0x31, 0x12);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr,
+ 0x52, 0xcd);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr,
+ 0x0e, 0xff);
+ val = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_CSI_PIX_EN_SEL_ADDR);
/* Output of SD core routed to MIPI CSI 4-lane Tx */
val |= ADV_REG_SETFIELD(0x10, IO_CTRL_CSI4_IN_SEL);
- ret |= adv7481_wr_byte(state->client, IO_REG_CSI_PIX_EN_SEL_ADDR, val);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_CSI_PIX_EN_SEL_ADDR, val);
/* Enable autodetect */
- ret |= adv7481_wr_byte(state->i2c_sdp, 0x0e, 0x81);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr,
+ 0x0e, 0x81);
return ret;
}
@@ -713,69 +1030,101 @@ static int adv7481_set_hdmi_mode(struct adv7481_state *state)
* YUV 422 out via TxA CSI: 4-Lane
*/
/* Disable chip powerdown & Enable HDMI Rx block */
- temp = adv7481_rd_byte(state->client, IO_REG_PWR_DOWN_CTRL_ADDR);
+ temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_PWR_DOWN_CTRL_ADDR);
val = ADV_REG_SETFIELD(1, IO_CTRL_RX_EN) |
ADV_REG_SETFIELD(0, IO_CTRL_RX_PWDN) |
ADV_REG_SETFIELD(0, IO_CTRL_XTAL_PWDN) |
ADV_REG_SETFIELD(0, IO_CTRL_CORE_PWDN) |
ADV_REG_SETFIELD(0, IO_CTRL_MASTER_PWDN);
- ret = adv7481_wr_byte(state->client, IO_REG_PWR_DOWN_CTRL_ADDR, val);
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_PWR_DOWN_CTRL_ADDR, val);
/* SDR mode */
- ret |= adv7481_wr_byte(state->client, 0x11, 0x48);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ 0x11, 0x48);
/* Set CP core to YUV out */
- ret |= adv7481_wr_byte(state->client, 0x04, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ 0x04, 0x00);
/* Set CP core to SDR 422 */
- ret |= adv7481_wr_byte(state->client, 0x12, 0xF2);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ 0x12, 0xF2);
/* Saturate both Luma and Chroma values to 254 */
- ret |= adv7481_wr_byte(state->client, 0x17, 0x80);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ 0x17, 0x80);
/* Set CP core to enable AV codes */
- ret |= adv7481_wr_byte(state->client, 0x03, 0x86);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ 0x03, 0x86);
/* ADI RS CP Core: */
- ret |= adv7481_wr_byte(state->i2c_cp, 0x7C, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_cp_addr,
+ 0x7C, 0x00);
/* Set CP core Phase Adjustment */
- ret |= adv7481_wr_byte(state->client, 0x0C, 0xE0);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ 0x0C, 0xE0);
/* LLC/PIX/SPI PINS TRISTATED AUD Outputs Enabled */
- ret |= adv7481_wr_byte(state->client, IO_PAD_CTRLS_ADDR, 0xDD);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_PAD_CTRLS_ADDR, 0xDD);
/* Enable Tx A CSI 4-Lane & data from CP core */
val = ADV_REG_SETFIELD(1, IO_CTRL_CSI4_EN) |
ADV_REG_SETFIELD(1, IO_CTRL_PIX_OUT_EN) |
ADV_REG_SETFIELD(0, IO_CTRL_CSI4_IN_SEL);
- ret |= adv7481_wr_byte(state->client, IO_REG_CSI_PIX_EN_SEL_ADDR,
- val);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_CSI_PIX_EN_SEL_ADDR, val);
/* start to configure HDMI Rx once io-map is configured */
/* Enable HDCP 1.1 */
- ret |= adv7481_wr_byte(state->i2c_rep, 0x40, 0x83);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_rep_addr,
+ 0x40, 0x83);
/* Foreground Channel = A */
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x00, 0x08);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x00, 0x08);
/* ADI Required Write */
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x98, 0xFF);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x99, 0xA3);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x9A, 0x00);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x9B, 0x0A);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x9D, 0x40);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0xCB, 0x09);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x98, 0xFF);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x99, 0xA3);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x9A, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x9B, 0x0A);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x9D, 0x40);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0xCB, 0x09);
/* ADI RS */
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x3D, 0x10);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x3E, 0x7B);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x3F, 0x5E);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x4E, 0xFE);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x4F, 0x18);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x57, 0xA3);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x58, 0x04);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x85, 0x10);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x3D, 0x10);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x3E, 0x7B);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x3F, 0x5E);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x4E, 0xFE);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x4F, 0x18);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x57, 0xA3);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x58, 0x04);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x85, 0x10);
/* Enable All Terminations */
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x83, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x83, 0x00);
/* ADI RS */
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0xA3, 0x01);
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0xBE, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0xA3, 0x01);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0xBE, 0x00);
/* HPA Manual Enable */
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x6C, 0x01);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x6C, 0x01);
/* HPA Asserted */
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0xF8, 0x01);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0xF8, 0x01);
/* Audio Mute Speed Set to Fastest (Smallest Step Size) */
- ret |= adv7481_wr_byte(state->i2c_hdmi, 0x0F, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ 0x0F, 0x00);
return ret;
}
@@ -860,7 +1209,7 @@ static int adv7481_set_ip_mode(struct adv7481_state *state, int input)
}
static int adv7481_set_op_src(struct adv7481_state *state,
- int output, int input)
+ int output, int input)
{
int ret = 0;
int temp = 0;
@@ -897,10 +1246,11 @@ static int adv7481_set_op_src(struct adv7481_state *state,
default:
ret = -EINVAL;
}
- temp = adv7481_rd_byte(state->client,
+ temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
IO_REG_PWR_DOWN_CTRL_ADDR);
temp |= val;
- adv7481_wr_byte(state->client, IO_REG_PWR_DOWN_CTRL_ADDR, temp);
+ adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_REG_PWR_DOWN_CTRL_ADDR, temp);
state->csia_src = input;
break;
case ADV7481_OP_CSIB:
@@ -915,11 +1265,11 @@ static int adv7481_set_op_src(struct adv7481_state *state,
return ret;
}
-static u32 ba_inp_to_adv7481(u32 input)
+static u32 ba_inp_to_adv7481(u32 ba_input)
{
u32 adv_input = ADV7481_IP_HDMI;
- switch (input) {
+ switch (ba_input) {
case BA_IP_CVBS_0:
adv_input = ADV7481_IP_CVBS_1;
break;
@@ -954,6 +1304,42 @@ static u32 ba_inp_to_adv7481(u32 input)
return adv_input;
}
+static u32 adv7481_inp_to_ba(u32 adv_input)
+{
+ u32 ba_input = BA_IP_HDMI_1;
+
+ switch (adv_input) {
+ case ADV7481_IP_CVBS_1:
+ ba_input = BA_IP_CVBS_0;
+ break;
+ case ADV7481_IP_CVBS_2:
+ ba_input = BA_IP_CVBS_1;
+ break;
+ case ADV7481_IP_CVBS_3:
+ ba_input = BA_IP_CVBS_2;
+ break;
+ case ADV7481_IP_CVBS_4:
+ ba_input = BA_IP_CVBS_3;
+ break;
+ case ADV7481_IP_CVBS_5:
+ ba_input = BA_IP_CVBS_4;
+ break;
+ case ADV7481_IP_CVBS_6:
+ ba_input = BA_IP_CVBS_5;
+ break;
+ case ADV7481_IP_HDMI:
+ ba_input = BA_IP_HDMI_1;
+ break;
+ case ADV7481_IP_TTL:
+ ba_input = BA_IP_TTL;
+ break;
+ default:
+ ba_input = BA_IP_HDMI_1;
+ break;
+ }
+ return ba_input;
+}
+
static int adv7481_s_routing(struct v4l2_subdev *sd, u32 input,
u32 output, u32 config)
{
@@ -986,6 +1372,27 @@ unlock_exit:
return ret;
}
+static bool adv7481_is_timing_locked(struct adv7481_state *state)
+{
+ bool ret = false;
+ int val1 = 0;
+ int val2 = 0;
+
+ /* Check Timing Lock IO Map Status3:0x71[0] && 0x71[1] && 0x71[7] */
+ val1 = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr,
+ IO_HDMI_LVL_RAW_STATUS_3_ADDR);
+ val2 = adv7481_rd_byte(&state->i2c_client, state->i2c_cp_addr,
+ CP_REG_STDI_CH_ADDR);
+
+ if (ADV_REG_GETFIELD(val1, IO_DE_REGEN_LCK_RAW) &&
+ ADV_REG_GETFIELD(val1, IO_V_LOCKED_RAW) &&
+ ADV_REG_GETFIELD(val1, IO_TMDSPLL_LCK_A_RAW) &&
+ ADV_REG_GETFIELD(val2, CP_STDI_DVALID_CH1))
+ ret = true;
+
+ return ret;
+}
+
static int adv7481_get_hdmi_timings(struct adv7481_state *state,
struct adv7481_vid_params *vid_params,
struct adv7481_hdmi_params *hdmi_params)
@@ -998,13 +1405,15 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state,
pr_debug("Enter %s\n", __func__);
/* Check TMDS PLL Lock and Frequency */
- temp1 = adv7481_rd_byte(state->i2c_hdmi, HDMI_REG_HDMI_PARAM4_ADDR);
+ temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ HDMI_REG_HDMI_PARAM4_ADDR);
hdmi_params->pll_lock = ADV_REG_GETFIELD(temp1,
HDMI_REG_TMDS_PLL_LOCKED);
if (hdmi_params->pll_lock) {
- temp1 = adv7481_rd_byte(state->i2c_hdmi,
- HDMI_REG_TMDS_FREQ_ADDR);
- temp2 = adv7481_rd_byte(state->i2c_hdmi,
+ temp1 = adv7481_rd_byte(&state->i2c_client,
+ state->i2c_hdmi_addr, HDMI_REG_TMDS_FREQ_ADDR);
+ temp2 = adv7481_rd_byte(&state->i2c_client,
+ state->i2c_hdmi_addr,
HDMI_REG_TMDS_FREQ_FRAC_ADDR);
hdmi_params->tmds_freq = ADV_REG_GETFIELD(temp1,
HDMI_REG_TMDS_FREQ);
@@ -1015,34 +1424,29 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state,
hdmi_params->tmds_freq += ADV_REG_GETFIELD(temp2,
HDMI_REG_TMDS_FREQ_FRAC)*ONE_MHZ_TO_HZ/128;
} else {
- pr_err("%s: PLL not locked return EBUSY\n", __func__);
- return -EBUSY;
+ pr_err("%s(%d): PLL not locked return EBUSY\n",
+ __func__, __LINE__);
+ ret = -EBUSY;
+ goto set_default;
}
- /* Check Timing Lock IO Map Status3:0x71[0] && 0x71[1] && 0x71[7] */
+ /* Check Timing Lock */
do {
- temp1 = adv7481_rd_byte(state->client,
- IO_HDMI_LVL_RAW_STATUS_3_ADDR);
- temp2 = adv7481_rd_byte(state->i2c_cp,
- CP_REG_STDI_CH_ADDR);
-
- if (ADV_REG_GETFIELD(temp1, IO_DE_REGEN_LCK_RAW) &&
- ADV_REG_GETFIELD(temp1, IO_V_LOCKED_RAW) &&
- ADV_REG_GETFIELD(temp1, IO_TMDSPLL_LCK_A_RAW) &&
- ADV_REG_GETFIELD(temp2, CP_STDI_DVALID_CH1))
+ if (adv7481_is_timing_locked(state))
break;
count++;
usleep_range(LOCK_MIN_SLEEP, LOCK_MAX_SLEEP);
} while (count < LOCK_NUM_TRIES);
if (count >= LOCK_NUM_TRIES) {
- pr_err("%s(%d), adv7481 HDMI DE regeneration block NOT Locked: 0x%x",
- __func__, __LINE__, temp1);
+ pr_err("%s(%d), HDMI DE regeneration block NOT Locked\n",
+ __func__, __LINE__);
}
/* Check Timing Lock HDMI Map V:0x07[7], H:0x7[5] */
do {
- temp1 = adv7481_rd_byte(state->i2c_hdmi,
+ temp1 = adv7481_rd_byte(&state->i2c_client,
+ state->i2c_hdmi_addr,
HDMI_REG_LINE_WIDTH_1_ADDR);
if (ADV_REG_GETFIELD(temp1, HDMI_VERT_FILTER_LOCKED) &&
@@ -1059,7 +1463,8 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state,
}
/* Check HDMI Parameters */
- temp1 = adv7481_rd_byte(state->i2c_hdmi, HDMI_REG_FIELD1_HEIGHT1_ADDR);
+ temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ HDMI_REG_FIELD1_HEIGHT1_ADDR);
hdmi_params->color_depth = ADV_REG_GETFIELD(temp1,
HDMI_REG_DEEP_COLOR_MODE);
@@ -1068,22 +1473,25 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state,
HDMI_REG_HDMI_INTERLACED);
fieldfactor = (vid_params->intrlcd == 1) ? 2 : 1;
- temp1 = adv7481_rd_byte(state->i2c_hdmi, HDMI_REG_HDMI_PARAM5_ADDR);
+ temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ HDMI_REG_HDMI_PARAM5_ADDR);
hdmi_params->pix_rep = ADV_REG_GETFIELD(temp1,
HDMI_REG_PIXEL_REPETITION);
/* Get Active Timing Data HDMI Map H:0x07[4:0] + 0x08[7:0] */
- temp1 = adv7481_rd_byte(state->i2c_hdmi, HDMI_REG_LINE_WIDTH_1_ADDR);
- temp2 = adv7481_rd_byte(state->i2c_hdmi, HDMI_REG_LINE_WIDTH_2_ADDR);
+ temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ HDMI_REG_LINE_WIDTH_1_ADDR);
+ temp2 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
+ HDMI_REG_LINE_WIDTH_2_ADDR);
vid_params->act_pix = (((ADV_REG_GETFIELD(temp1,
HDMI_REG_LINE_WIDTH_1) << 8) & 0x1F00) |
ADV_REG_GETFIELD(temp2,
HDMI_REG_LINE_WIDTH_2));
/* Get Total Timing Data HDMI Map H:0x1E[5:0] + 0x1F[7:0] */
- temp1 = adv7481_rd_byte(state->i2c_hdmi,
+ temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
HDMI_REG_TOTAL_LINE_WIDTH_1_ADDR);
- temp2 = adv7481_rd_byte(state->i2c_hdmi,
+ temp2 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
HDMI_REG_TOTAL_LINE_WIDTH_2_ADDR);
vid_params->tot_pix = (((ADV_REG_GETFIELD(temp1,
HDMI_REG_TOTAL_LINE_WIDTH_1) << 8) & 0x3F00) |
@@ -1091,9 +1499,9 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state,
HDMI_REG_TOTAL_LINE_WIDTH_2));
/* Get Active Timing Data HDMI Map V:0x09[4:0] + 0x0A[7:0] */
- temp1 = adv7481_rd_byte(state->i2c_hdmi,
+ temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
HDMI_REG_FIELD0_HEIGHT_1_ADDR);
- temp2 = adv7481_rd_byte(state->i2c_hdmi,
+ temp2 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
HDMI_REG_FIELD0_HEIGHT_2_ADDR);
vid_params->act_lines = (((ADV_REG_GETFIELD(temp1,
HDMI_REG_FIELD0_HEIGHT_1) << 8) & 0x1F00) |
@@ -1101,9 +1509,9 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state,
HDMI_REG_FIELD0_HEIGHT_2));
/* Get Total Timing Data HDMI Map V:0x26[5:0] + 0x27[7:0] */
- temp1 = adv7481_rd_byte(state->i2c_hdmi,
+ temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
HDMI_REG_FIELD0_TOTAL_HEIGHT_1_ADDR);
- temp2 = adv7481_rd_byte(state->i2c_hdmi,
+ temp2 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
HDMI_REG_FIELD0_TOTAL_HEIGHT_2_ADDR);
vid_params->tot_lines = (((ADV_REG_GETFIELD(temp1,
HDMI_REG_FIELD0_TOT_HEIGHT_1) << 8) & 0x3F00) |
@@ -1139,6 +1547,18 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state,
(hdmi_params->pix_rep + 1));
}
+set_default:
+ if (ret) {
+ pr_debug("%s(%d), error %d resort to default fmt\n",
+ __func__, __LINE__, ret);
+ vid_params->act_pix = MAX_DEFAULT_WIDTH;
+ vid_params->act_lines = MAX_DEFAULT_HEIGHT;
+ vid_params->fr_rate = MAX_DEFAULT_FRAME_RATE;
+ vid_params->pix_clk = MAX_DEFAULT_PIX_CLK_HZ;
+ vid_params->intrlcd = 0;
+ ret = 0;
+ }
+
pr_debug("%s(%d), adv7481 TMDS Resolution: %d x %d @ %d fps\n",
__func__, __LINE__,
vid_params->act_pix, vid_params->act_lines,
@@ -1170,15 +1590,22 @@ static int adv7481_query_dv_timings(struct v4l2_subdev *sd,
switch (state->mode) {
case ADV7481_IP_HDMI:
case ADV7481_IP_CVBS_1_HDMI_SIM:
- adv7481_get_hdmi_timings(state, &vid_params, &hdmi_params);
- timings->type = V4L2_DV_BT_656_1120;
- bt_timings->width = vid_params.act_pix;
- bt_timings->height = vid_params.act_lines;
- bt_timings->pixelclock = vid_params.pix_clk;
- bt_timings->interlaced = vid_params.intrlcd ?
+ ret = adv7481_get_hdmi_timings(state, &vid_params,
+ &hdmi_params);
+ if (!ret) {
+ timings->type = V4L2_DV_BT_656_1120;
+ bt_timings->width = vid_params.act_pix;
+ bt_timings->height = vid_params.act_lines;
+ bt_timings->pixelclock = vid_params.pix_clk;
+ bt_timings->interlaced = vid_params.intrlcd ?
V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE;
- if (bt_timings->interlaced == V4L2_DV_INTERLACED)
- bt_timings->height /= 2;
+ if (bt_timings->interlaced == V4L2_DV_INTERLACED)
+ bt_timings->height /= 2;
+ } else {
+ pr_err(
+ "%s: Error in adv7481_get_hdmi_timings. ret %d\n",
+ __func__, ret);
+ }
break;
default:
return -EINVAL;
@@ -1195,7 +1622,8 @@ static int adv7481_query_sd_std(struct v4l2_subdev *sd, v4l2_std_id *std)
uint8_t tStatus = 0x0;
pr_debug("Enter %s\n", __func__);
- tStatus = adv7481_rd_byte(state->i2c_sdp, SDP_RO_MAIN_STATUS1_ADDR);
+ tStatus = adv7481_rd_byte(&state->i2c_client, state->i2c_sdp_addr,
+ SDP_RO_MAIN_STATUS1_ADDR);
if (!ADV_REG_GETFIELD(tStatus, SDP_RO_MAIN_IN_LOCK))
pr_err("%s(%d), adv7481 SD Input NOT Locked: 0x%x\n",
__func__, __LINE__, tStatus);
@@ -1267,11 +1695,17 @@ static int adv7481_g_mbus_fmt(struct v4l2_subdev *sd,
switch (state->mode) {
case ADV7481_IP_HDMI:
case ADV7481_IP_CVBS_1_HDMI_SIM:
- adv7481_get_hdmi_timings(state, &vid_params, &hdmi_params);
- fmt->width = vid_params.act_pix;
- fmt->height = vid_params.act_lines;
- if (vid_params.intrlcd)
- fmt->height /= 2;
+ ret = adv7481_get_hdmi_timings(state, &vid_params,
+ &hdmi_params);
+ if (!ret) {
+ fmt->width = vid_params.act_pix;
+ fmt->height = vid_params.act_lines;
+ if (vid_params.intrlcd)
+ fmt->height /= 2;
+ } else {
+ pr_err("%s: Error %d in adv7481_get_hdmi_timings\n",
+ __func__, ret);
+ }
break;
default:
return -EINVAL;
@@ -1290,17 +1724,17 @@ static int adv7481_set_audio_spdif(struct adv7481_state *state,
if (on) {
/* Configure I2S_SDATA output pin as an SPDIF output 0x6E[3] */
- val = adv7481_rd_byte(state->i2c_hdmi,
+ val = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
HDMI_REG_MUX_SPDIF_TO_I2S_ADDR);
val |= ADV_REG_SETFIELD(1, HDMI_MUX_SPDIF_TO_I2S_EN);
- ret = adv7481_wr_byte(state->i2c_hdmi,
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
HDMI_REG_MUX_SPDIF_TO_I2S_ADDR, val);
} else {
/* Configure I2S_SDATA output pin as an I2S output 0x6E[3] */
- val = adv7481_rd_byte(state->i2c_hdmi,
+ val = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr,
HDMI_REG_MUX_SPDIF_TO_I2S_ADDR);
val &= ~ADV_REG_SETFIELD(1, HDMI_MUX_SPDIF_TO_I2S_EN);
- ret = adv7481_wr_byte(state->i2c_hdmi,
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr,
HDMI_REG_MUX_SPDIF_TO_I2S_ADDR, val);
}
return ret;
@@ -1310,40 +1744,42 @@ static int adv7481_csi_powerdown(struct adv7481_state *state,
enum adv7481_output output)
{
int ret;
- struct i2c_client *csi_map;
+ uint8_t csi_map;
uint8_t val = 0;
pr_debug("Enter %s for output: %d\n", __func__, output);
/* Select CSI TX to configure data */
if (output == ADV7481_OP_CSIA) {
- csi_map = state->i2c_csi_txa;
+ csi_map = state->i2c_csi_txa_addr;
} else if (output == ADV7481_OP_CSIB) {
- csi_map = state->i2c_csi_txb;
+ csi_map = state->i2c_csi_txb_addr;
} else if (output == ADV7481_OP_TTL) {
/* For now use TxA */
- csi_map = state->i2c_csi_txa;
+ csi_map = state->i2c_csi_txa_addr;
} else {
/* Default to TxA */
- csi_map = state->i2c_csi_txa;
+ csi_map = state->i2c_csi_txa_addr;
}
/* CSI Tx: power down DPHY */
- ret = adv7481_wr_byte(csi_map, CSI_REG_TX_DPHY_PWDN_ADDR,
+ ret = adv7481_wr_byte(&state->i2c_client, csi_map,
+ CSI_REG_TX_DPHY_PWDN_ADDR,
ADV_REG_SETFIELD(1, CSI_CTRL_DPHY_PWDN));
/* ADI Required Write */
- ret |= adv7481_wr_byte(csi_map, 0x31, 0x82);
- ret |= adv7481_wr_byte(csi_map, 0x1e, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x31, 0x82);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x1e, 0x00);
/* CSI TxA: # Lane : Power Off */
val = ADV_REG_SETFIELD(1, CSI_CTRL_TX_PWRDN) |
ADV_REG_SETFIELD(state->tx_lanes, CSI_CTRL_NUM_LANES);
- ret |= adv7481_wr_byte(csi_map, CSI_REG_TX_CFG1_ADDR, val);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map,
+ CSI_REG_TX_CFG1_ADDR, val);
/*
* ADI Recommended power down sequence
* DPHY and CSI Tx A Power down Sequence
* CSI TxA: MIPI PLL DIS
*/
- ret |= adv7481_wr_byte(csi_map, 0xda, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xda, 0x00);
/* ADI Required Write */
- ret |= adv7481_wr_byte(csi_map, 0xc1, 0x3b);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xc1, 0x3b);
pr_debug("Exit %s, ret: %d\n", __func__, ret);
@@ -1354,7 +1790,7 @@ static int adv7481_csi_powerup(struct adv7481_state *state,
enum adv7481_output output)
{
int ret;
- struct i2c_client *csi_map;
+ uint8_t csi_map;
uint8_t val = 0;
uint8_t csi_sel = 0;
@@ -1364,7 +1800,7 @@ static int adv7481_csi_powerup(struct adv7481_state *state,
csi_sel = ADV_REG_SETFIELD(1, IO_CTRL_CSI4_EN) |
ADV_REG_SETFIELD(1, IO_CTRL_PIX_OUT_EN) |
ADV_REG_SETFIELD(0, IO_CTRL_CSI4_IN_SEL);
- csi_map = state->i2c_csi_txa;
+ csi_map = state->i2c_csi_txa_addr;
} else if (output == ADV7481_OP_CSIB) {
/* Enable 1-Lane MIPI Tx, enable pixel output and
* route SD through Pixel port
@@ -1373,54 +1809,57 @@ static int adv7481_csi_powerup(struct adv7481_state *state,
ADV_REG_SETFIELD(1, IO_CTRL_PIX_OUT_EN) |
ADV_REG_SETFIELD(1, IO_CTRL_SD_THRU_PIX_OUT) |
ADV_REG_SETFIELD(0, IO_CTRL_CSI4_IN_SEL);
- csi_map = state->i2c_csi_txb;
+ csi_map = state->i2c_csi_txb_addr;
} else if (output == ADV7481_OP_TTL) {
/* For now use TxA */
- csi_map = state->i2c_csi_txa;
+ csi_map = state->i2c_csi_txa_addr;
} else {
/* Default to TxA */
- csi_map = state->i2c_csi_txa;
+ csi_map = state->i2c_csi_txa_addr;
}
/* Enable Tx A/B CSI #-lane */
- ret = adv7481_wr_byte(state->client,
+ ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr,
IO_REG_CSI_PIX_EN_SEL_ADDR, csi_sel);
/* TXA MIPI lane settings for CSI */
/* CSI TxA: # Lane : Power Off */
val = ADV_REG_SETFIELD(1, CSI_CTRL_TX_PWRDN) |
ADV_REG_SETFIELD(state->tx_lanes, CSI_CTRL_NUM_LANES);
- ret |= adv7481_wr_byte(csi_map, CSI_REG_TX_CFG1_ADDR, val);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map,
+ CSI_REG_TX_CFG1_ADDR, val);
/* CSI TxA: Auto D-PHY Timing */
val |= ADV_REG_SETFIELD(1, CSI_CTRL_AUTO_PARAMS);
- ret |= adv7481_wr_byte(csi_map, CSI_REG_TX_CFG1_ADDR, val);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map,
+ CSI_REG_TX_CFG1_ADDR, val);
/* DPHY and CSI Tx A */
- ret |= adv7481_wr_byte(csi_map, 0xdb, 0x10);
- ret |= adv7481_wr_byte(csi_map, 0xd6, 0x07);
- ret |= adv7481_wr_byte(csi_map, 0xc4, 0x0a);
- ret |= adv7481_wr_byte(csi_map, 0x71, 0x33);
- ret |= adv7481_wr_byte(csi_map, 0x72, 0x11);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xdb, 0x10);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xd6, 0x07);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xc4, 0x0a);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x71, 0x33);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x72, 0x11);
/* CSI TxA: power up DPHY */
- ret |= adv7481_wr_byte(csi_map, 0xf0, 0x00);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xf0, 0x00);
/* ADI Required Write */
- ret |= adv7481_wr_byte(csi_map, 0x31, 0x82);
- ret |= adv7481_wr_byte(csi_map, 0x1e, 0x40);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x31, 0x82);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x1e, 0x40);
/* adi Recommended power up sequence */
/* DPHY and CSI Tx A Power up Sequence */
/* CSI TxA: MIPI PLL EN */
- ret |= adv7481_wr_byte(csi_map, 0xda, 0x01);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xda, 0x01);
msleep(200);
/* CSI TxA: # MIPI Lane : Power ON */
val = ADV_REG_SETFIELD(0, CSI_CTRL_TX_PWRDN) |
ADV_REG_SETFIELD(1, CSI_CTRL_AUTO_PARAMS) |
ADV_REG_SETFIELD(state->tx_lanes, CSI_CTRL_NUM_LANES);
- ret |= adv7481_wr_byte(csi_map, CSI_REG_TX_CFG1_ADDR, val);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map,
+ CSI_REG_TX_CFG1_ADDR, val);
msleep(100);
/* ADI Required Write */
- ret |= adv7481_wr_byte(csi_map, 0xc1, 0x2b);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xc1, 0x2b);
msleep(100);
/* ADI Required Write */
- ret |= adv7481_wr_byte(csi_map, 0x31, 0x80);
+ ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x31, 0x80);
pr_debug("Exit %s, ret: %d\n", __func__, ret);
@@ -1476,42 +1915,30 @@ static int adv7481_g_input_status(struct v4l2_subdev *sd, u32 *status)
{
int ret = 0;
struct adv7481_state *state = to_state(sd);
- uint8_t val1 = 0;
- uint8_t val2 = 0;
+ uint8_t val = 0;
uint32_t count = 0;
pr_debug("Enter %s\n", __func__);
if (ADV7481_IP_HDMI == state->mode) {
- /*
- * Check Timing Lock IO Map Status3:0x71[0] &&
- * 0x71[1] && 0x71[7]
- */
+ /* Check Timing Lock */
do {
- val1 = adv7481_rd_byte(state->client,
- IO_HDMI_LVL_RAW_STATUS_3_ADDR);
- val2 = adv7481_rd_byte(state->i2c_cp,
- CP_REG_STDI_CH_ADDR);
-
- if (ADV_REG_GETFIELD(val1, IO_DE_REGEN_LCK_RAW) &&
- ADV_REG_GETFIELD(val1, IO_V_LOCKED_RAW) &&
- ADV_REG_GETFIELD(val1, IO_TMDSPLL_LCK_A_RAW) &&
- ADV_REG_GETFIELD(val2, CP_STDI_DVALID_CH1))
+ if (adv7481_is_timing_locked(state))
break;
count++;
usleep_range(LOCK_MIN_SLEEP, LOCK_MAX_SLEEP);
} while (count < LOCK_NUM_TRIES);
if (count >= LOCK_NUM_TRIES) {
- pr_err("%s(%d), HDMI DE regeneration block NOT Locked: 0x%x, 0x%x",
- __func__, __LINE__, val1, val2);
+ pr_err("%s(%d), HDMI DE regeneration block NOT Locked\n",
+ __func__, __LINE__);
*status |= V4L2_IN_ST_NO_SIGNAL;
}
} else {
- val1 = adv7481_rd_byte(state->i2c_sdp,
+ val = adv7481_rd_byte(&state->i2c_client, state->i2c_sdp_addr,
SDP_RO_MAIN_STATUS1_ADDR);
- if (!ADV_REG_GETFIELD(val1, SDP_RO_MAIN_IN_LOCK)) {
+ if (!ADV_REG_GETFIELD(val, SDP_RO_MAIN_IN_LOCK)) {
pr_err("%s(%d), SD Input NOT Locked: 0x%x\n",
- __func__, __LINE__, val1);
+ __func__, __LINE__, val);
*status |= V4L2_IN_ST_NO_SIGNAL;
}
}
@@ -1539,6 +1966,7 @@ static const struct v4l2_subdev_video_ops adv7481_video_ops = {
static const struct v4l2_subdev_core_ops adv7481_core_ops = {
.s_power = adv7481_s_power,
+ .ioctl = adv7481_ioctl,
};
static const struct v4l2_ctrl_ops adv7481_ctrl_ops = {
@@ -1552,6 +1980,8 @@ static const struct v4l2_subdev_ops adv7481_ops = {
static int adv7481_init_v4l2_controls(struct adv7481_state *state)
{
+ int ret = 0;
+
v4l2_ctrl_handler_init(&state->ctrl_hdl, 4);
v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7481_ctrl_ops,
@@ -1565,59 +1995,218 @@ static int adv7481_init_v4l2_controls(struct adv7481_state *state)
state->sd.ctrl_handler = &state->ctrl_hdl;
if (state->ctrl_hdl.error) {
- int err = state->ctrl_hdl.error;
+ ret = state->ctrl_hdl.error;
v4l2_ctrl_handler_free(&state->ctrl_hdl);
- return err;
+ } else {
+ v4l2_ctrl_handler_setup(&state->ctrl_hdl);
}
- v4l2_ctrl_handler_setup(&state->ctrl_hdl);
- return 0;
+ pr_err("%s: Exit with ret: %d\n", __func__, ret);
+ return ret;
+}
+
+static struct msm_camera_i2c_fn_t msm_sensor_cci_func_tbl = {
+ .i2c_read = msm_camera_cci_i2c_read,
+ .i2c_read_seq = msm_camera_cci_i2c_read_seq,
+ .i2c_write = msm_camera_cci_i2c_write,
+ .i2c_write_table = msm_camera_cci_i2c_write_table,
+ .i2c_write_seq_table = msm_camera_cci_i2c_write_seq_table,
+ .i2c_write_table_w_microdelay =
+ msm_camera_cci_i2c_write_table_w_microdelay,
+ .i2c_util = msm_sensor_cci_i2c_util,
+ .i2c_poll = msm_camera_cci_i2c_poll,
+};
+
+static int adv7481_cci_init(struct adv7481_state *state)
+{
+ struct msm_camera_cci_client *cci_client = NULL;
+ int ret = 0;
+
+ pr_err("%s: Enter\n", __func__);
+
+ state->i2c_client.i2c_func_tbl = &msm_sensor_cci_func_tbl;
+ state->i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
+ state->i2c_client.cci_client = kzalloc(sizeof(
+ struct msm_camera_cci_client), GFP_KERNEL);
+ cci_client = state->i2c_client.cci_client;
+ if (!cci_client) {
+ ret = -ENOMEM;
+ goto err_cci_init;
+ }
+ cci_client->cci_subdev = msm_cci_get_subdev();
+ pr_debug("%s cci_subdev: %p\n", __func__, cci_client->cci_subdev);
+ cci_client->cci_i2c_master = state->cci_master;
+ cci_client->sid = state->i2c_slave_addr;
+ cci_client->retries = 3;
+ cci_client->id_map = 0;
+ cci_client->i2c_freq_mode = I2C_FAST_MODE;
+ ret = state->i2c_client.i2c_func_tbl->i2c_util(
+ &state->i2c_client, MSM_CCI_INIT);
+ if (ret < 0)
+ pr_err("%s - cci_init failed\n", __func__);
+
+ pr_debug("%s i2c_client.client: %p\n", __func__,
+ state->i2c_client.client);
+
+err_cci_init:
+ return ret;
+}
+
+static int adv7481_parse_dt(struct adv7481_state *state)
+{
+ struct device_node *np = state->dev->of_node;
+ unsigned int i;
+ int gpio_count = 0;
+ int flag_count = 0;
+ int label_count = 0;
+ int ret = 0;
+
+ /* config CCI */
+ ret = of_property_read_u32(np, "qcom,cci-master",
+ &state->cci_master);
+ if (ret < 0 || state->cci_master >= MASTER_MAX) {
+ pr_err("%s: failed ret %d\n", __func__, ret);
+ goto exit;
+ }
+ pr_debug("%s: cci_master: 0x%x\n", __func__, state->cci_master);
+ ret = of_property_read_u32(np, "qcom,slave-addr",
+ &state->i2c_slave_addr);
+ if (ret < 0) {
+ pr_err("%s: failed ret %d\n", __func__, ret);
+ goto exit;
+ }
+ pr_debug("%s: i2c_slave_addr: 0x%x\n", __func__, state->i2c_slave_addr);
+ state->i2c_io_addr = (uint8_t)state->i2c_slave_addr;
+
+ ret = of_property_read_u32(np, "qcom,csi-slave-addr",
+ &state->i2c_csi_slave_addr);
+ if (ret < 0) {
+ pr_err("%s: failed ret %d\n", __func__, ret);
+ goto exit;
+ }
+ pr_debug("%s: i2c_csi_slave_addr: 0x%x\n", __func__,
+ state->i2c_csi_slave_addr);
+ ret = of_property_read_u32(np, "qcom,vpp-slave-addr",
+ &state->i2c_vpp_slave_addr);
+ if (ret < 0) {
+ pr_err("%s: failed ret %d\n", __func__, ret);
+ goto exit;
+ }
+ pr_debug("%s: i2c_vpp_slave_addr: 0x%x\n", __func__,
+ state->i2c_vpp_slave_addr);
+
+ ret = adv7481_cci_init(state);
+ if (ret < 0) {
+ pr_err("%s: failed adv7481_cci_init ret %d\n", __func__, ret);
+ goto exit;
+ }
+ /* Configure GPIOs */
+ gpio_count = of_gpio_count(np);
+ pr_debug("%s: of_gpio_count: 0x%x\n", __func__, gpio_count);
+ flag_count = of_property_count_u32_elems(np, "qcom,gpio-tbl-flags");
+ pr_debug("%s: gpio-tbl-flags: 0x%x\n", __func__, flag_count);
+ label_count = of_property_count_strings(np, "qcom,gpio-tbl-label");
+ pr_debug("%s: gpio-tbl-label: 0x%x\n", __func__, label_count);
+ if (gpio_count != ADV7481_GPIO_MAX ||
+ flag_count != ADV7481_GPIO_MAX ||
+ label_count != ADV7481_GPIO_MAX) {
+ ret = -EFAULT;
+ pr_err("%s: failed to configure GPIO ret -EFAULT\n", __func__);
+ goto exit;
+ }
+ for (i = 0; i < ADV7481_GPIO_MAX; i++) {
+ u32 tmp;
+
+ state->gpio_array[i].gpio = of_get_gpio(np, i);
+ of_property_read_u32_index(np, "qcom,gpio-tbl-flags", i, &tmp);
+ state->gpio_array[i].flags = tmp;
+ of_property_read_string_index(np, "qcom,gpio-tbl-label", i,
+ &state->gpio_array[i].label);
+ pr_debug("%s: gpio_array[%d] = %d\n", __func__, i,
+ state->gpio_array[i].gpio);
+ }
+ pr_debug("%s: End read back gpio from dt...", __func__);
+
+exit:
+ return ret;
}
-static int adv7481_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static const struct of_device_id adv7481_id[] = {
+ { .compatible = "qcom,adv7481", },
+ { /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, adv7481_id);
+
+static int adv7481_probe(struct platform_device *pdev)
{
struct adv7481_state *state;
+ const struct of_device_id *device_id;
struct adv7481_platform_data *pdata = NULL;
struct v4l2_subdev *sd;
- struct v4l2_ctrl_handler *hdl;
int ret;
- pr_debug("Attempting to probe...\n");
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_BYTE_DATA)) {
- pr_err("%s %s Check i2c Functionality Fail\n",
- __func__, client->name);
- ret = -EIO;
+ device_id = of_match_device(adv7481_id, &pdev->dev);
+ if (!device_id) {
+ pr_err("%s: device_id is NULL\n", __func__);
+ ret = -ENODEV;
goto err;
}
- v4l_info(client, "chip found @ 0x%02x (%s)\n",
- client->addr, client->adapter->name);
/* Create 7481 State */
- state = devm_kzalloc(&client->dev,
- sizeof(struct adv7481_state), GFP_KERNEL);
+ state = devm_kzalloc(&pdev->dev,
+ sizeof(struct adv7481_state), GFP_KERNEL);
if (state == NULL) {
ret = -ENOMEM;
- pr_err("Check Kzalloc Fail\n");
- goto err_mem;
+ goto err;
}
- state->client = client;
+ state->dev = &pdev->dev;
+
mutex_init(&state->mutex);
+ /* config VREG */
+ ret = msm_camera_get_dt_vreg_data(pdev->dev.of_node,
+ &(state->cci_vreg), &(state->regulator_count));
+ if (ret < 0) {
+ pr_err("%s:cci get_dt_vreg failed\n", __func__);
+ goto err_mem_free;
+ }
+
+ ret = msm_camera_config_vreg(&pdev->dev, state->cci_vreg,
+ state->regulator_count, NULL, 0,
+ &state->cci_reg_ptr[0], 1);
+ if (ret < 0) {
+ pr_err("%s:cci config_vreg failed\n", __func__);
+ goto err_mem_free;
+ }
+
+ ret = msm_camera_enable_vreg(&pdev->dev, state->cci_vreg,
+ state->regulator_count, NULL, 0,
+ &state->cci_reg_ptr[0], 1);
+ if (ret < 0) {
+ pr_err("%s:cci enable_vreg failed\n", __func__);
+ goto err_mem_free;
+ }
+ pr_debug("%s - VREG Initialized...\n", __func__);
+
+ ret = adv7481_parse_dt(state);
+ pr_debug("%s - Done parsing dt...\n", __func__);
+
/* Get and Check Platform Data */
- pdata = (struct adv7481_platform_data *) client->dev.platform_data;
+ pdata = (struct adv7481_platform_data *) pdev->dev.platform_data;
if (!pdata) {
ret = -ENOMEM;
- pr_err("Getting Platform data failed\n");
- goto err_mem;
+ pr_err("%s(%d): Getting Platform data failed\n",
+ __func__, __LINE__);
+ goto err_mem_free;
}
- /* Configure and Register V4L2 I2C Sub-device */
+ /* Configure and Register V4L2 Sub-device */
sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &adv7481_ops);
+ v4l2_subdev_init(sd, &adv7481_ops);
+ sd->owner = pdev->dev.driver->owner;
+ v4l2_set_subdevdata(sd, state);
+ strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
state->sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
@@ -1627,32 +2216,35 @@ static int adv7481_probe(struct i2c_client *client,
ret = media_entity_init(&state->sd.entity, 1, &state->pad, 0);
if (ret) {
ret = -EIO;
- pr_err("Media entity init failed\n");
+ pr_err("%s(%d): Media entity init failed\n",
+ __func__, __LINE__);
goto err_media_entity;
}
/* Initialize HW Config */
- ret = adv7481_hw_init(pdata, state);
+ ret = adv7481_hw_init(state);
if (ret) {
ret = -EIO;
- pr_err("HW Initialisation Failed\n");
+ pr_err("%s: HW Initialisation Failed\n", __func__);
goto err_media_entity;
}
/* Register V4l2 Control Functions */
- hdl = &state->ctrl_hdl;
- v4l2_ctrl_handler_init(hdl, 4);
- adv7481_init_v4l2_controls(state);
+ ret = adv7481_init_v4l2_controls(state);
+ if (ret) {
+ pr_err("%s: V4L2 Controls Initialisation Failed %d\n",
+ __func__, ret);
+ }
- /* Initials ADV7481 State Settings */
+ /* Initial ADV7481 State Settings */
state->tx_auto_params = ADV7481_AUTO_PARAMS;
- state->tx_lanes = ADV7481_MIPI_2LANE;
/* Initialize SW Init Settings and I2C sub maps 7481 */
- ret = adv7481_dev_init(state, client);
+ ret = adv7481_dev_init(state);
if (ret) {
ret = -EIO;
- pr_err("SW Initialisation Failed\n");
+ pr_err("%s(%d): SW Initialisation Failed\n",
+ __func__, __LINE__);
goto err_media_entity;
}
@@ -1672,7 +2264,7 @@ static int adv7481_probe(struct i2c_client *client,
err_media_entity:
media_entity_cleanup(&sd->entity);
-err_mem:
+err_mem_free:
kfree(state);
err:
if (!ret)
@@ -1680,50 +2272,39 @@ err:
return ret;
}
-static int adv7481_remove(struct i2c_client *client)
+static int adv7481_remove(struct platform_device *pdev)
{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct adv7481_state *state = to_state(sd);
+ struct adv7481_state *state;
- msm_ba_unregister_subdev_node(sd);
- v4l2_device_unregister_subdev(sd);
- media_entity_cleanup(&sd->entity);
+ state = pdev->dev.platform_data;
+ msm_ba_unregister_subdev_node(&state->sd);
+ v4l2_device_unregister_subdev(&state->sd);
+ media_entity_cleanup(&state->sd.entity);
v4l2_ctrl_handler_free(&state->ctrl_hdl);
+ adv7481_reset_irq(state);
if (state->irq > 0)
free_irq(state->irq, state);
- i2c_unregister_device(state->i2c_csi_txa);
- i2c_unregister_device(state->i2c_csi_txb);
- i2c_unregister_device(state->i2c_hdmi);
- i2c_unregister_device(state->i2c_edid);
- i2c_unregister_device(state->i2c_cp);
- i2c_unregister_device(state->i2c_sdp);
- i2c_unregister_device(state->i2c_rep);
+ cancel_delayed_work(&state->irq_delayed_work);
mutex_destroy(&state->mutex);
kfree(state);
return 0;
}
-static const struct i2c_device_id adv7481_id[] = {
- { DRIVER_NAME, 0 },
- {},
-};
-MODULE_DEVICE_TABLE(i2c, adv7481_id);
-
-
-static struct i2c_driver adv7481_driver = {
+static struct platform_driver adv7481_driver = {
.driver = {
.owner = THIS_MODULE,
.name = KBUILD_MODNAME,
+ .of_match_table = adv7481_id,
},
.probe = adv7481_probe,
.remove = adv7481_remove,
- .id_table = adv7481_id,
};
-module_i2c_driver(adv7481_driver);
+module_driver(adv7481_driver, platform_driver_register,
+ platform_driver_unregister);
MODULE_DESCRIPTION("ADI ADV7481 HDMI/MHL/SD video receiver");
diff --git a/drivers/media/i2c/adv7481_reg.h b/drivers/media/i2c/adv7481_reg.h
index a4e14fa18e0a..a2dffa978b6d 100644
--- a/drivers/media/i2c/adv7481_reg.h
+++ b/drivers/media/i2c/adv7481_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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,155 +19,233 @@
#define ADV_REG_GETFIELD(val, field) \
(((val) & (field##_BMSK)) >> (field##_SHFT))
+#define ADV_REG_RSTFIELD(val, field) \
+ ((val) & ~((field##_BMSK) << (field##_SHFT)))
+
/* IO Map Registers */
-#define IO_REG_MAIN_RST_ADDR 0xFF
-#define IO_REG_MAIN_RST_VALUE 0xFF
-
-#define IO_REG_PWR_DOWN_CTRL_ADDR 0x00
-#define IO_CTRL_RX_EN_BMSK 0x0040
-#define IO_CTRL_RX_EN_SHFT 6
-#define IO_CTRL_RX_PWDN_BMSK 0x0020
-#define IO_CTRL_RX_PWDN_SHFT 5
-#define IO_CTRL_XTAL_PWDN_BMSK 0x0004
-#define IO_CTRL_XTAL_PWDN_SHFT 2
-#define IO_CTRL_CORE_PWDN_BMSK 0x0002
-#define IO_CTRL_CORE_PWDN_SHFT 1
-#define IO_CTRL_MASTER_PWDN_BMSK 0x0001
-#define IO_CTRL_MASTER_PWDN_SHFT 0
-
-#define IO_REG_PWR_DN2_XTAL_HIGH_ADDR 0x01
-#define IO_CTRL_CEC_WAKE_UP_PWRDN2B_BMSK 0x0080
-#define IO_CTRL_CEC_WAKE_UP_PWRDN2B_SHFT 7
+#define IO_REG_MAIN_RST_ADDR 0xFF
+#define IO_REG_MAIN_RST_VALUE 0xFF
+
+#define IO_REG_PWR_DOWN_CTRL_ADDR 0x00
+#define IO_CTRL_RX_EN_BMSK 0x0040
+#define IO_CTRL_RX_EN_SHFT 6
+#define IO_CTRL_RX_PWDN_BMSK 0x0020
+#define IO_CTRL_RX_PWDN_SHFT 5
+#define IO_CTRL_XTAL_PWDN_BMSK 0x0004
+#define IO_CTRL_XTAL_PWDN_SHFT 2
+#define IO_CTRL_CORE_PWDN_BMSK 0x0002
+#define IO_CTRL_CORE_PWDN_SHFT 1
+#define IO_CTRL_MASTER_PWDN_BMSK 0x0001
+#define IO_CTRL_MASTER_PWDN_SHFT 0
+
+#define IO_REG_PWR_DN2_XTAL_HIGH_ADDR 0x01
+#define IO_CTRL_CEC_WAKE_UP_PWRDN2B_BMSK 0x0080
+#define IO_CTRL_CEC_WAKE_UP_PWRDN2B_SHFT 7
#define IO_CTRL_CEC_WAKE_UP_PWRDNB_BMSK 0x0040
#define IO_CTRL_CEC_WAKE_UP_PWRDNB_SHFT 6
-#define IO_PROG_XTAL_FREQ_HIGH_BMSK 0x003F
-#define IO_PROG_XTAL_FREQ_HIGH_SHFT 0
+#define IO_PROG_XTAL_FREQ_HIGH_BMSK 0x003F
+#define IO_PROG_XTAL_FREQ_HIGH_SHFT 0
-#define IO_REG_XTAL_FREQ_LOW_ADDR 0x02
-#define IO_PROG_XTAL_FREQ_LOW_BMSK 0x00FF
-#define IO_PROG_XTAL_FREQ_LOW_SHFT 0
+#define IO_REG_XTAL_FREQ_LOW_ADDR 0x02
+#define IO_PROG_XTAL_FREQ_LOW_BMSK 0x00FF
+#define IO_PROG_XTAL_FREQ_LOW_SHFT 0
-#define IO_REG_CP_VID_STD_ADDR 0x05
+#define IO_REG_CP_VID_STD_ADDR 0x05
-#define IO_REG_CSI_PIX_EN_SEL_ADDR 0x10
-#define IO_CTRL_CSI4_EN_BMSK 0x0080
-#define IO_CTRL_CSI4_EN_SHFT 7
-#define IO_CTRL_CSI1_EN_BMSK 0x0040
-#define IO_CTRL_CSI1_EN_SHFT 6
+#define IO_REG_CSI_PIX_EN_SEL_ADDR 0x10
+#define IO_CTRL_CSI4_EN_BMSK 0x0080
+#define IO_CTRL_CSI4_EN_SHFT 7
+#define IO_CTRL_CSI1_EN_BMSK 0x0040
+#define IO_CTRL_CSI1_EN_SHFT 6
#define IO_CTRL_PIX_OUT_EN_BMSK 0x0020
#define IO_CTRL_PIX_OUT_EN_SHFT 5
-#define IO_CTRL_SD_THRU_PIX_OUT_BMSK 0x0010
-#define IO_CTRL_SD_THRU_PIX_OUT_SHFT 4
-#define IO_CTRL_CSI4_IN_SEL_BMSK 0x000C
-#define IO_CTRL_CSI4_IN_SEL_SHFT 2
+#define IO_CTRL_SD_THRU_PIX_OUT_BMSK 0x0010
+#define IO_CTRL_SD_THRU_PIX_OUT_SHFT 4
+#define IO_CTRL_CSI4_IN_SEL_BMSK 0x000C
+#define IO_CTRL_CSI4_IN_SEL_SHFT 2
-#define IO_PAD_CTRLS_ADDR 0x0E
+#define IO_PAD_CTRLS_ADDR 0x0E
+#define IO_PAD_FILTER_CTRLS_ADDR 0x0F
-#define IO_REG_I2C_CFG_ADDR 0xF2
+#define IO_REG_I2C_CFG_ADDR 0xF2
#define IO_REG_I2C_AUTOINC_EN_REG_VALUE 0x01
-#define IO_CTRL_MASTER_PWDN_REG_VALUE 0x01
-
-#define IO_HDMI_LVL_RAW_STATUS_3_ADDR 0x71
-#define IO_TMDSPLL_LCK_A_RAW_BMSK 0x0080
-#define IO_TMDSPLL_LCK_A_RAW_SHFT 7
-#define IO_CABLE_DET_A_RAW_BMSK 0x0040
-#define IO_CABLE_DET_A_RAW_SHFT 6
-#define IO_V_LOCKED_RAW_BMSK 0x0002
-#define IO_V_LOCKED_RAW_SHFT 1
-#define IO_DE_REGEN_LCK_RAW_BMSK 0x0001
-#define IO_DE_REGEN_LCK_RAW_SHFT 0
+#define IO_CTRL_MASTER_PWDN_REG_VALUE 0x01
/* Interrupts */
-#define IO_HDMI_LVL_INT_STATUS_3_ADDR 0x72
-#define IO_CABLE_DET_A_ST_BMSK 0x0040
-#define IO_CABLE_DET_A_ST_SHFT 6
+#define IO_HDMI_LVL_INT_CLEAR_1_ADDR 0x69
-#define IO_HDMI_LVL_INT_CLEAR_3_ADDR 0x73
+#define IO_HDMI_LVL_INT_MASKB_1_ADDR 0x6B
+#define IO_AVI_INFO_MB1_BMSK 0x0001
+#define IO_AVI_INFO_MB1_SHFT 0
+
+#define IO_HDMI_LVL_INT_CLEAR_2_ADDR 0x6E
+
+#define IO_HDMI_LVL_RAW_STATUS_3_ADDR 0x71
+#define IO_TMDSPLL_LCK_A_RAW_BMSK 0x0080
+#define IO_TMDSPLL_LCK_A_RAW_SHFT 7
+#define IO_CABLE_DET_A_RAW_BMSK 0x0040
+#define IO_CABLE_DET_A_RAW_SHFT 6
+#define IO_V_LOCKED_RAW_BMSK 0x0002
+#define IO_V_LOCKED_RAW_SHFT 1
+#define IO_DE_REGEN_LCK_RAW_BMSK 0x0001
+#define IO_DE_REGEN_LCK_RAW_SHFT 0
+
+#define IO_HDMI_LVL_INT_STATUS_3_ADDR 0x72
+#define IO_CABLE_DET_A_ST_BMSK 0x0040
+#define IO_CABLE_DET_A_ST_SHFT 6
+#define IO_V_LOCKED_ST_BMSK 0x0002
+#define IO_V_LOCKED_ST_SHFT 1
+#define IO_DE_REGEN_LCK_ST_BMSK 0x0001
+#define IO_DE_REGEN_LCK_ST_SHFT 0
+
+#define IO_HDMI_LVL_INT_CLEAR_3_ADDR 0x73
#define IO_CABLE_DET_A_CLR_BMSK 0x0040
#define IO_CABLE_DET_A_CLR_SHFT 6
-#define IO_HDMI_LVL_INT2_MASKB_3_ADDR 0x74
+#define IO_HDMI_LVL_INT2_MASKB_3_ADDR 0x74
#define IO_CABLE_DET_A_MB2_BMSK 0x0040
#define IO_CABLE_DET_A_MB2_SHFT 6
-#define IO_HDMI_LVL_INT_MASKB_3_ADDR 0x75
+#define IO_HDMI_LVL_INT_MASKB_3_ADDR 0x75
#define IO_CABLE_DET_A_MB1_BMSK 0x0040
#define IO_CABLE_DET_A_MB1_SHFT 6
-
-#define IO_REG_PAD_CTRL_1_ADDR 0x1D
-#define IO_PDN_INT1_BMSK 0x0080
-#define IO_PDN_INT1_SHFT 7
-#define IO_PDN_INT2_BMSK 0x0040
-#define IO_PDN_INT2_SHFT 6
-#define IO_PDN_INT3_BMSK 0x0020
-#define IO_PDN_INT3_SHFT 5
+#define IO_V_LOCKED_MB1_BMSK 0x0002
+#define IO_V_LOCKED_MB1_SHFT 1
+#define IO_DE_REGEN_LCK_MB1_BMSK 0x0001
+#define IO_DE_REGEN_LCK_MB1_SHFT 0
+
+#define IO_HDMI_EDG_RAW_STATUS_1_ADDR 0x80
+#define IO_NEW_AVI_INFO_RAW_BMSK 0x0001
+#define IO_NEW_AVI_INFO_RAW_SHFT 0
+
+#define IO_HDMI_EDG_INT_STATUS_1_ADDR 0x81
+#define IO_NEW_AVI_INFO_ST_BMSK 0x0001
+#define IO_NEW_AVI_INFO_ST_SHFT 0
+
+#define IO_HDMI_EDG_INT_CLEAR_1_ADDR 0x82
+#define IO_NEW_AVI_INFO_CLR_BMSK 0x0001
+#define IO_NEW_AVI_INFO_CLR_SHFT 0
+
+#define IO_HDMI_EDG_INT2_MASKB_1_ADDR 0x83
+#define IO_NEW_AVI_INFO_MB2_BMSK 0x0001
+#define IO_NEW_AVI_INFO_MB2_SHFT 0
+
+#define IO_HDMI_EDG_INT_MASKB_1_ADDR 0x84
+#define IO_NEW_AVI_INFO_MB1_BMSK 0x0001
+#define IO_NEW_AVI_INFO_MB1_SHFT 0
+
+#define IO_HDMI_EDG_INT_CLEAR_2_ADDR 0x87
+#define IO_HDMI_EDG_INT_CLEAR_3_ADDR 0x8C
+
+#define IO_REG_PAD_CTRL_1_ADDR 0x1D
+#define IO_PDN_INT1_BMSK 0x0080
+#define IO_PDN_INT1_SHFT 7
+#define IO_PDN_INT2_BMSK 0x0040
+#define IO_PDN_INT2_SHFT 6
+#define IO_PDN_INT3_BMSK 0x0020
+#define IO_PDN_INT3_SHFT 5
#define IO_INV_LLC_BMSK 0x0010
#define IO_INV_LLC_SHFT 4
-#define IO_DRV_LLC_PAD_BMSK 0x000C
-#define IO_DRV_LLC_PAD_SHFT 2
-
-#define IO_REG_INT_RAW_STATUS_ADDR 0x3F
-
-#define IO_REG_INT1_CONF_ADDR 0x40
-#define IO_INTRQ_DUR_SEL_BMSK 0x00C0
-#define IO_INTRQ_DUR_SEL_SHFT 6
-#define IO_INTRQ_OP_SEL_BMSK 0x0003
-#define IO_INTRQ_OP_SEL_SHFT 0
-
-#define IO_REG_INT2_CONF_ADDR 0x41
-#define IO_INTRQ2_DUR_SEL_BMSK 0x00C0
-#define IO_INTRQ2_DUR_SEL_SHFT 6
+#define IO_DRV_LLC_PAD_BMSK 0x000C
+#define IO_DRV_LLC_PAD_SHFT 2
+
+#define IO_REG_INT_RAW_STATUS_ADDR 0x3F
+#define IO_INT_CEC_ST_BMSK 0x0010
+#define IO_INT_CEC_ST_SHFT 4
+#define IO_INT_HDMI_ST_BMSK 0x0008
+#define IO_INT_HDMI_ST_SHFT 3
+#define IO_INTRQ3_RAW_BMSK 0x0004
+#define IO_INTRQ3_RAW_SHFT 2
+#define IO_INTRQ2_RAW_BMSK 0x0002
+#define IO_INTRQ2_RAW_SHFT 1
+#define IO_INTRQ1_RAW_BMSK 0x0001
+#define IO_INTRQ1_RAW_SHFT 0
+
+#define IO_REG_INT1_CONF_ADDR 0x40
+#define IO_INTRQ_DUR_SEL_BMSK 0x00C0
+#define IO_INTRQ_DUR_SEL_SHFT 6
+#define IO_INTRQ_OP_SEL_BMSK 0x0003
+#define IO_INTRQ_OP_SEL_SHFT 0
+
+#define IO_REG_INT2_CONF_ADDR 0x41
+#define IO_INTRQ2_DUR_SEL_BMSK 0x00C0
+#define IO_INTRQ2_DUR_SEL_SHFT 6
#define IO_CP_LOCK_UNLOCK_EDGE_SEL_BMSK 0x0020
#define IO_CP_LOCK_UNLOCK_EDGE_SEL_SHFT 5
-#define IO_EN_UMASK_RAW_INTRQ2_BMSK 0x0008
-#define IO_EN_UMASK_RAW_INTRQ2_SHFT 3
+#define IO_EN_UMASK_RAW_INTRQ2_BMSK 0x0008
+#define IO_EN_UMASK_RAW_INTRQ2_SHFT 3
#define IO_INT2_EN_BMSK 0x0004
#define IO_INT2_EN_SHFT 2
-#define IO_INTRQ2_OP_SEL_BMSK 0x0003
-#define IO_INTRQ2_OP_SEL_SHFT 0
+#define IO_INTRQ2_OP_SEL_BMSK 0x0003
+#define IO_INTRQ2_OP_SEL_SHFT 0
#define IO_REG_DATAPATH_RAW_STATUS_ADDR 0x43
+#define IO_CP_LOCK_CP_RAW_BMSK 0x0080
+#define IO_CP_LOCK_CP_RAW_SHFT 7
+#define IO_CP_UNLOCK_CP_RAW_BMSK 0x0040
+#define IO_CP_UNLOCK_CP_RAW_SHFT 6
+#define IO_VMUTE_REQUEST_HDMI_RAW_BMSK 0x0020
+#define IO_VMUTE_REQUEST_HDMI_RAW_SHFT 5
+#define IO_MPU_STIM_INTRQ_RAW_BMSK 0x0002
+#define IO_MPU_STIM_INTRQ_RAW_SHFT 1
+#define IO_INT_SD_RAW_BMSK 0x0001
+#define IO_INT_SD_RAW_SHFT 0
+
#define IO_REG_DATAPATH_INT_STATUS_ADDR 0x44
-#define IO_REG_DATAPATH_INT_CLEAR_ADDR 0x45
-
-#define IO_REG_DATAPATH_INT_MASKB_ADDR 0x47
-#define IO_CP_LOCK_CP_MB1_BMSK 0x0080
-#define IO_CP_LOCK_CP_MB1_SHFT 7
-#define IO_CP_UNLOCK_CP_MB1_BMSK 0x0040
-#define IO_CP_UNLOCK_CP_MB1_SHFT 6
-#define IO_VMUTE_REQUEST_HDMI_MB1_BMSK 0x0020
-#define IO_VMUTE_REQUEST_HDMI_MB1_SHFT 5
-#define IO_MPU_STIM_INTRQ_MB1_BMSK 0x0002
-#define IO_MPU_STIM_INTRQ_MB1_SHFT 1
-#define IO_INT_SD_MB1_BMSK 0x0001
-#define IO_INT_SD_MB1_SHFT 0
+#define IO_CP_LOCK_CP_ST_BMSK 0x0080
+#define IO_CP_LOCK_CP_ST_SHFT 7
+#define IO_CP_UNLOCK_CP_ST_BMSK 0x0040
+#define IO_CP_UNLOCK_CP_ST_SHFT 6
+#define IO_VMUTE_REQUEST_HDMI_ST_BMSK 0x0020
+#define IO_VMUTE_REQUEST_HDMI_ST_SHFT 5
+#define IO_MPU_STIM_INTRQ_ST_BMSK 0x0002
+#define IO_MPU_STIM_INTRQ_ST_SHFT 1
+#define IO_INT_SD_ST_BMSK 0x0001
+#define IO_INT_SD_ST_SHFT 0
+
+#define IO_REG_DATAPATH_INT_CLEAR_ADDR 0x45
+
+#define IO_REG_DATAPATH_INT_MASKB_ADDR 0x47
+#define IO_CP_LOCK_CP_MB1_BMSK 0x0080
+#define IO_CP_LOCK_CP_MB1_SHFT 7
+#define IO_CP_UNLOCK_CP_MB1_BMSK 0x0040
+#define IO_CP_UNLOCK_CP_MB1_SHFT 6
+#define IO_VMUTE_REQUEST_HDMI_MB1_BMSK 0x0020
+#define IO_VMUTE_REQUEST_HDMI_MB1_SHFT 5
+#define IO_MPU_STIM_INTRQ_MB1_BMSK 0x0002
+#define IO_MPU_STIM_INTRQ_MB1_SHFT 1
+#define IO_INT_SD_MB1_BMSK 0x0001
+#define IO_INT_SD_MB1_SHFT 0
+
+#define IO_REG_CHIP_REV_ID_1_ADDR 0xDF
+#define IO_REG_CHIP_REV_ID_2_ADDR 0xE0
/* Offsets */
-#define IO_REG_DPLL_ADDR 0xF3
-#define IO_REG_CP_ADDR 0xF4
-#define IO_REG_HDMI_ADDR 0xF5
-#define IO_REG_EDID_ADDR 0xF6
-#define IO_REG_HDMI_REP_ADDR 0xF7
-#define IO_REG_HDMI_INF_ADDR 0xF8
-#define IO_REG_CBUS_ADDR 0xF9
-#define IO_REG_CEC_ADDR 0xFA
-#define IO_REG_SDP_ADDR 0xFB
-#define IO_REG_CSI_TXB_ADDR 0xFC
-#define IO_REG_CSI_TXA_ADDR 0xFD
+#define IO_REG_DPLL_ADDR 0xF3
+#define IO_REG_CP_ADDR 0xF4
+#define IO_REG_HDMI_ADDR 0xF5
+#define IO_REG_EDID_ADDR 0xF6
+#define IO_REG_HDMI_REP_ADDR 0xF7
+#define IO_REG_HDMI_INF_ADDR 0xF8
+#define IO_REG_CBUS_ADDR 0xF9
+#define IO_REG_CEC_ADDR 0xFA
+#define IO_REG_SDP_ADDR 0xFB
+#define IO_REG_CSI_TXB_ADDR 0xFC
+#define IO_REG_CSI_TXA_ADDR 0xFD
/* Sub Address Map Locations */
-#define IO_REG_DPLL_SADDR 0x4C
-#define IO_REG_CP_SADDR 0x44
-#define IO_REG_HDMI_SADDR 0x74
-#define IO_REG_EDID_SADDR 0x78
-#define IO_REG_HDMI_REP_SADDR 0x64
-#define IO_REG_HDMI_INF_SADDR 0x62
-#define IO_REG_CBUS_SADDR 0xF0
-#define IO_REG_CEC_SADDR 0x82
-#define IO_REG_SDP_SADDR 0xF2
-#define IO_REG_CSI_TXB_SADDR 0x90
-#define IO_REG_CSI_TXA_SADDR 0x94
+#define IO_REG_DPLL_SADDR 0x4C
+#define IO_REG_CP_SADDR 0x44
+#define IO_REG_HDMI_SADDR 0x74
+#define IO_REG_EDID_SADDR 0x78
+#define IO_REG_HDMI_REP_SADDR 0x64
+#define IO_REG_HDMI_INF_SADDR 0x62
+#define IO_REG_CBUS_SADDR 0xF0
+#define IO_REG_CEC_SADDR 0x82
+#define IO_REG_SDP_SADDR 0xF2
+#define IO_REG_CSI_TXB_SADDR 0x90
+#define IO_REG_CSI_TXA_SADDR 0x94
/* HDMI Map Registers */
#define HDMI_REG_HDMI_PARAM4_ADDR 0x04
@@ -179,10 +257,10 @@
#define HDMI_REG_AUDIO_PLL_LOCKED_SHFT 0
#define HDMI_REG_HDMI_PARAM5_ADDR 0x05
-#define HDMI_REG_HDMI_MODE_BMSK 0x0080
+#define HDMI_REG_HDMI_MODE_BMSK 0x0080
#define HDMI_REG_TMDS_FREQ_0_SHFT 7
-#define HDMI_REG_HDMI_CONT_ENCRYPT_BMSK 0x0040
-#define HDMI_REG_HDMI_CONT_ENCRYPT_SHFT 6
+#define HDMI_REG_HDMI_CONT_ENCRYPT_BMSK 0x0040
+#define HDMI_REG_HDMI_CONT_ENCRYPT_SHFT 6
#define HDMI_REG_DVI_HSYNC_POLARITY_BMSK 0x0020
#define HDMI_REG_DVI_HSYNC_POLARITY_SHFT 5
#define HDMI_REG_DVI_VSYNC_POLARITY_BMSK 0x0010
@@ -233,13 +311,13 @@
#define HDMI_REG_FIELD0_TOT_HEIGHT_2_BMSK 0x00FF
#define HDMI_REG_FIELD0_TOT_HEIGHT_2_SHFT 0
-#define HDMI_REG_DIS_CABLE_DET_RST_ADDR 0x48
+#define HDMI_REG_DIS_CABLE_DET_RST_ADDR 0x48
#define HDMI_DIS_CABLE_DET_RST_BMSK 0x0040
#define HDMI_DIS_CABLE_DET_RST_SHFT 6
-#define HDMI_REG_TMDS_FREQ_ADDR 0x51
-#define HDMI_REG_TMDS_FREQ_BMSK 0x00FF
-#define HDMI_REG_TMDS_FREQ_SHFT 0
+#define HDMI_REG_TMDS_FREQ_ADDR 0x51
+#define HDMI_REG_TMDS_FREQ_BMSK 0x00FF
+#define HDMI_REG_TMDS_FREQ_SHFT 0
#define HDMI_REG_TMDS_FREQ_FRAC_ADDR 0x52
#define HDMI_REG_TMDS_FREQ_0_BMSK 0x0080
@@ -247,7 +325,7 @@
#define HDMI_REG_TMDS_FREQ_FRAC_BMSK 0x007F
#define HDMI_REG_TMDS_FREQ_FRAC_SHFT 0
-#define HDMI_REG_RST_CTRLS_ADDR 0x5A
+#define HDMI_REG_RST_CTRLS_ADDR 0x5A
#define HDMI_HDCP_REPT_EDID_RST_BMSK 0x0008
#define HDMI_HDCP_REPT_EDID_RST_SHFT 3
@@ -261,19 +339,55 @@
#define HDMI_MAN_EDID_A_ENABLE_SHFT 0
#define HDMI_REG_RO_EDID_DEBUG_2_ADDR 0x76
-#define HDMI_EDID_A_ENABLE_BMSK 0x0001
-#define HDMI_EDID_A_ENABLE_SHFT 0
+#define HDMI_EDID_A_ENABLE_BMSK 0x0001
+#define HDMI_EDID_A_ENABLE_SHFT 0
+
+/* CEC Map Registers */
+#define CEC_REG_LOG_ADDR_MASK_ADDR 0x27
+#define CEC_REG_LOG_ADDR_MASK2_BMSK 0x0040
+#define CEC_REG_LOG_ADDR_MASK2_SHFT 6
+#define CEC_REG_LOG_ADDR_MASK1_BMSK 0x0020
+#define CEC_REG_LOG_ADDR_MASK1_SHFT 5
+#define CEC_REG_LOG_ADDR_MASK0_BMSK 0x0010
+#define CEC_REG_LOG_ADDR_MASK0_SHFT 4
+#define CEC_REG_ERROR_REPORT_MODE_BMSK 0x0008
+#define CEC_REG_ERROR_REPORT_MODE_SHFT 3
+#define CEC_REG_ERROR_REPORT_DET_BMSK 0x0004
+#define CEC_REG_ERROR_REPORT_DET_SHFT 2
+#define CEC_REG_FORCE_NACK_BMSK 0x0002
+#define CEC_REG_FORCE_NACK_SHFT 1
+#define CEC_REG_FORCE_IGNORE_BMSK 0x0001
+#define CEC_REG_FORCE_IGNORE_SHFT 0
+
+#define CEC_REG_LOGICAL_ADDRESS0_1_ADDR 0x28
+#define CEC_REG_LOGICAL_ADDRESS1_BMSK 0x00F0
+#define CEC_REG_LOGICAL_ADDRESS1_SHFT 4
+#define CEC_REG_LOGICAL_ADDRESS0_BMSK 0x000F
+#define CEC_REG_LOGICAL_ADDRESS0_SHFT 0
+
+#define CEC_REG_LOGICAL_ADDRESS2_ADDR 0x29
+#define CEC_REG_LOGICAL_ADDRESS2_BMSK 0x000F
+#define CEC_REG_LOGICAL_ADDRESS2_SHFT 0
+
+#define CEC_REG_CEC_POWER_UP_ADDR 0x2A
+#define CEC_REG_CEC_POWER_UP_BMSK 0x0001
+#define CEC_REG_CEC_POWER_UP_SHFT 0
+
+#define CEC_REG_CLR_RX_RDY_SFT_RST_ADDR 0x2C
+#define CEC_REG_CEC_SOFT_RESET_BMSK 0x0001
+#define CEC_REG_CEC_SOFT_RESET_SHFT 0
+
/* CP Map Registers */
-#define CP_REG_CONTRAST 0x3A
-#define CP_REG_SATURATION 0x3B
-#define CP_REG_BRIGHTNESS 0x3C
-#define CP_REG_HUE 0x3D
-#define CP_REG_VID_ADJ 0x3E
-#define CP_CTR_VID_ADJ_EN 0x80
+#define CP_REG_CONTRAST 0x3A
+#define CP_REG_SATURATION 0x3B
+#define CP_REG_BRIGHTNESS 0x3C
+#define CP_REG_HUE 0x3D
+#define CP_REG_VID_ADJ 0x3E
+#define CP_CTR_VID_ADJ_EN 0x80
#define CP_REG_STDI_CH_ADDR 0xB1
-#define CP_STDI_DVALID_CH1_BMSK 0x0080
-#define CP_STDI_DVALID_CH1_SHFT 7
+#define CP_STDI_DVALID_CH1_BMSK 0x0080
+#define CP_STDI_DVALID_CH1_SHFT 7
/* SDP R/O Main Map Registers */
#define SDP_RO_MAIN_STATUS1_ADDR 0x10
@@ -298,50 +412,50 @@
#define CSI_CTRL_TX_PWRDN_SHFT 7
#define CSI_CTRL_AUTO_PARAMS_BMSK 0x0020
#define CSI_CTRL_AUTO_PARAMS_SHFT 5
-#define CSI_CTRL_NUM_LANES_BMSK 0x0007
-#define CSI_CTRL_NUM_LANES_SHFT 0
+#define CSI_CTRL_NUM_LANES_BMSK 0x0007
+#define CSI_CTRL_NUM_LANES_SHFT 0
#define CSI_REG_TX_DPHY_PWDN_ADDR 0xF0
-#define CSI_CTRL_DPHY_PWDN_BMSK 0x0001
-#define CSI_CTRL_DPHY_PWDN_SHFT 0
+#define CSI_CTRL_DPHY_PWDN_BMSK 0x0001
+#define CSI_CTRL_DPHY_PWDN_SHFT 0
enum adv7481_adresult {
- AD_NTSM_M_J = 0x0,
- AD_NTSC_4_43 = 0x1,
- AD_PAL_M = 0x2,
- AD_PAL_60 = 0x3,
- AD_PAL_B_G = 0x4,
- AD_SECAM = 0x5,
- AD_PAL_COMB_N = 0x6,
- AD_SECAM_525 = 0x7,
+ AD_NTSM_M_J = 0x0,
+ AD_NTSC_4_43 = 0x1,
+ AD_PAL_M = 0x2,
+ AD_PAL_60 = 0x3,
+ AD_PAL_B_G = 0x4,
+ AD_SECAM = 0x5,
+ AD_PAL_COMB_N = 0x6,
+ AD_SECAM_525 = 0x7,
};
enum adv7481_color_depth {
- CD_8BIT = 0x0,
- CD_10BIT = 0x1,
- CD_12BIT = 0x2,
- CD_16BIT = 0x3,
+ CD_8BIT = 0x0,
+ CD_10BIT = 0x1,
+ CD_12BIT = 0x2,
+ CD_16BIT = 0x3,
};
enum adv7481_intrq_dur_sel {
- AD_4_XTAL_PER = 0x0,
- AD_16_XTAL_PER = 0x1,
- AD_64_XTAL_PER = 0x2,
- AD_ACTIVE_UNTIL_CLR = 0x3,
+ AD_4_XTAL_PER = 0x0,
+ AD_16_XTAL_PER = 0x1,
+ AD_64_XTAL_PER = 0x2,
+ AD_ACTIVE_UNTIL_CLR = 0x3,
};
enum adv7481_intrq_op_sel {
- AD_OP_OPEN_DRAIN = 0x0,
- AD_OP_DRIVE_LOW = 0x1,
- AD_OP_DRIVE_HIGH = 0x2,
- AD_OP_DISABLED = 0x3,
+ AD_OP_OPEN_DRAIN = 0x0,
+ AD_OP_DRIVE_LOW = 0x1,
+ AD_OP_DRIVE_HIGH = 0x2,
+ AD_OP_DISABLED = 0x3,
};
enum adv7481_drv_llc_pad {
- AD_LLC_PAD_NOT_USED = 0x0,
- AD_MIN_DRIVE_STRNGTH = 0x1,
- AD_MID_DRIVE_STRNGTH = 0x2,
- AD_MAX_DRIVE_STRNGTH = 0x3,
+ AD_LLC_PAD_NOT_USED = 0x0,
+ AD_MIN_DRIVE_STRNGTH = 0x1,
+ AD_MID_DRIVE_STRNGTH = 0x2,
+ AD_MAX_DRIVE_STRNGTH = 0x3,
};
#endif
diff --git a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
index e703791fd8e6..5d5ceb75653c 100644
--- a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
+++ b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
@@ -229,7 +229,7 @@ static void cam_smmu_print_list(int idx)
pr_err("index = %d ", idx);
list_for_each_entry(mapping,
&iommu_cb_set.cb_info[idx].smmu_buf_list, list) {
- pr_err("ion_fd = %d, paddr= 0x%p, len = %u\n",
+ pr_err("ion_fd = %d, paddr= 0x%pK, len = %u\n",
mapping->ion_fd, (void *)mapping->paddr,
(unsigned int)mapping->len);
}
@@ -240,10 +240,10 @@ static void cam_smmu_print_table(void)
int i;
for (i = 0; i < iommu_cb_set.cb_num; i++) {
- pr_err("i= %d, handle= %d, name_addr=%p\n", i,
+ pr_err("i= %d, handle= %d, name_addr=%pK\n", i,
(int)iommu_cb_set.cb_info[i].handle,
(void *)iommu_cb_set.cb_info[i].name);
- pr_err("dev = %p ", iommu_cb_set.cb_info[i].dev);
+ pr_err("dev = %pK ", iommu_cb_set.cb_info[i].dev);
}
}
@@ -306,18 +306,18 @@ static void cam_smmu_check_vaddr_in_range(int idx, void *vaddr)
end_addr = (unsigned long)mapping->paddr + mapping->len;
if (start_addr <= current_addr && current_addr < end_addr) {
- pr_err("Error: va %p is valid: range:%p-%p, fd = %d cb: %s\n",
+ pr_err("Error: va %pK is valid: range:%pK-%pK, fd = %d cb: %s\n",
vaddr, (void *)start_addr, (void *)end_addr,
mapping->ion_fd,
iommu_cb_set.cb_info[idx].name);
return;
} else {
- CDBG("va %p is not in this range: %p-%p, fd = %d\n",
+ CDBG("va %pK is not in this range: %pK-%pK, fd = %d\n",
vaddr, (void *)start_addr, (void *)end_addr,
mapping->ion_fd);
}
}
- pr_err("Cannot find vaddr:%p in SMMU. %s uses invalid virtual address\n",
+ pr_err("Cannot find vaddr:%pK in SMMU. %s uses invalid virtual address\n",
vaddr, iommu_cb_set.cb_info[idx].name);
return;
}
@@ -393,7 +393,7 @@ static int cam_smmu_iommu_fault_handler(struct iommu_domain *domain,
if (!token) {
pr_err("Error: token is NULL\n");
- pr_err("Error: domain = %p, device = %p\n", domain, dev);
+ pr_err("Error: domain = %pK, device = %pK\n", domain, dev);
pr_err("iova = %lX, flags = %d\n", iova, flags);
return 0;
}
@@ -705,7 +705,7 @@ static void cam_smmu_clean_buffer_list(int idx)
list_for_each_entry_safe(mapping_info, temp,
&iommu_cb_set.cb_info[idx].smmu_buf_list, list) {
- CDBG("Free mapping address %p, i = %d, fd = %d\n",
+ CDBG("Free mapping address %pK, i = %d, fd = %d\n",
(void *)mapping_info->paddr, idx,
mapping_info->ion_fd);
@@ -800,11 +800,11 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd,
}
if (table->sgl) {
- CDBG("DMA buf: %p, device: %p, attach: %p, table: %p\n",
+ CDBG("DMA buf: %pK, device: %pK, attach: %pK, table: %pK\n",
(void *)buf,
(void *)iommu_cb_set.cb_info[idx].dev,
(void *)attach, (void *)table);
- CDBG("table sgl: %p, rc: %d, dma_address: 0x%x\n",
+ CDBG("table sgl: %pK, rc: %d, dma_address: 0x%x\n",
(void *)table->sgl, rc,
(unsigned int)table->sgl->dma_address);
} else {
@@ -838,7 +838,7 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd,
rc = -ENOSPC;
goto err_unmap_sg;
}
- CDBG("ion_fd = %d, dev = %p, paddr= %p, len = %u\n", ion_fd,
+ CDBG("ion_fd = %d, dev = %pK, paddr= %pK, len = %u\n", ion_fd,
(void *)iommu_cb_set.cb_info[idx].dev,
(void *)*paddr_ptr, (unsigned int)*len_ptr);
@@ -862,10 +862,10 @@ static int cam_smmu_unmap_buf_and_remove_from_list(
{
if ((!mapping_info->buf) || (!mapping_info->table) ||
(!mapping_info->attach)) {
- pr_err("Error: Invalid params dev = %p, table = %p",
+ pr_err("Error: Invalid params dev = %pK, table = %pK",
(void *)iommu_cb_set.cb_info[idx].dev,
(void *)mapping_info->table);
- pr_err("Error:dma_buf = %p, attach = %p\n",
+ pr_err("Error:dma_buf = %pK, attach = %pK\n",
(void *)mapping_info->buf,
(void *)mapping_info->attach);
return -EINVAL;
@@ -989,7 +989,7 @@ static int cam_smmu_alloc_scratch_buffer_add_to_list(int idx,
CDBG("%s: nents = %lu, idx = %d, virt_len = %zx\n",
__func__, nents, idx, virt_len);
- CDBG("%s: phys_len = %zx, iommu_dir = %d, virt_addr = %p\n",
+ CDBG("%s: phys_len = %zx, iommu_dir = %d, virt_addr = %pK\n",
__func__, phys_len, iommu_dir, virt_addr);
/* This table will go inside the 'mapping' structure
@@ -1055,7 +1055,7 @@ static int cam_smmu_alloc_scratch_buffer_add_to_list(int idx,
mapping_info->ref_count = 1;
mapping_info->phys_len = phys_len;
- CDBG("%s: paddr = %p, len = %zx, phys_len = %zx",
+ CDBG("%s: paddr = %pK, len = %zx, phys_len = %zx",
__func__, (void *)mapping_info->paddr,
mapping_info->len, mapping_info->phys_len);
@@ -1093,7 +1093,7 @@ static int cam_smmu_free_scratch_buffer_remove_from_list(
&iommu_cb_set.cb_info[idx].scratch_map;
if (!mapping_info->table) {
- pr_err("Error: Invalid params: dev = %p, table = %p, ",
+ pr_err("Error: Invalid params: dev = %pK, table = %pK, ",
(void *)iommu_cb_set.cb_info[idx].dev,
(void *)mapping_info->table);
return -EINVAL;
diff --git a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c
index 33e1299cd027..21ac680bc9ae 100644
--- a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c
+++ b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c
@@ -165,7 +165,7 @@ int msm_camera_get_clk_info(struct platform_device *pdev,
rc = PTR_ERR((*clk_ptr)[i]);
goto err4;
}
- CDBG("clk ptr[%d] :%p\n", i, (*clk_ptr)[i]);
+ CDBG("clk ptr[%d] :%pK\n", i, (*clk_ptr)[i]);
}
devm_kfree(&pdev->dev, rates);
@@ -289,7 +289,7 @@ int msm_camera_get_clk_info_and_rates(
rc = PTR_ERR(clks[i]);
goto err5;
}
- CDBG("clk ptr[%d] :%p\n", i, clks[i]);
+ CDBG("clk ptr[%d] :%pK\n", i, clks[i]);
}
*pclk_info = clk_info;
*pclks = clks;
@@ -405,7 +405,7 @@ long msm_camera_clk_set_rate(struct device *dev,
if (!dev || !clk || (clk_rate < 0))
return -EINVAL;
- CDBG("clk : %p, enable : %ld\n", clk, clk_rate);
+ CDBG("clk : %pK, enable : %ld\n", clk, clk_rate);
if (clk_rate > 0) {
rate = clk_round_rate(clk, clk_rate);
@@ -436,7 +436,7 @@ int msm_camera_put_clk_info(struct platform_device *pdev,
if (clk_ptr[i] != NULL)
devm_clk_put(&pdev->dev, (*clk_ptr)[i]);
- CDBG("clk ptr[%d] :%p\n", i, (*clk_ptr)[i]);
+ CDBG("clk ptr[%d] :%pK\n", i, (*clk_ptr)[i]);
}
devm_kfree(&pdev->dev, *clk_info);
devm_kfree(&pdev->dev, *clk_ptr);
@@ -460,7 +460,7 @@ int msm_camera_put_clk_info_and_rates(struct platform_device *pdev,
for (i = cnt - 1; i >= 0; i--) {
if (clk_ptr[i] != NULL)
devm_clk_put(&pdev->dev, (*clk_ptr)[i]);
- CDBG("clk ptr[%d] :%p\n", i, (*clk_ptr)[i]);
+ CDBG("clk ptr[%d] :%pK\n", i, (*clk_ptr)[i]);
}
devm_kfree(&pdev->dev, *clk_info);
devm_kfree(&pdev->dev, *clk_ptr);
@@ -531,7 +531,7 @@ int msm_camera_get_regulator_info(struct platform_device *pdev,
rc = -EINVAL;
goto err1;
}
- CDBG("vdd ptr[%d] :%p\n", i, tmp_reg[i].vdd);
+ CDBG("vdd ptr[%d] :%pK\n", i, tmp_reg[i].vdd);
}
*num_reg = cnt;
@@ -607,7 +607,7 @@ void msm_camera_put_regulators(struct platform_device *pdev,
for (i = cnt - 1; i >= 0; i--) {
if (vdd_info[i] && !IS_ERR_OR_NULL(vdd_info[i]->vdd))
devm_regulator_put(vdd_info[i]->vdd);
- CDBG("vdd ptr[%d] :%p\n", i, vdd_info[i]->vdd);
+ CDBG("vdd ptr[%d] :%pK\n", i, vdd_info[i]->vdd);
}
devm_kfree(&pdev->dev, *vdd_info);
@@ -646,7 +646,7 @@ int msm_camera_register_irq(struct platform_device *pdev,
rc = -EINVAL;
}
- CDBG("Registered irq for %s[resource - %p]\n", irq_name, irq);
+ CDBG("Registered irq for %s[resource - %pK]\n", irq_name, irq);
return rc;
}
@@ -671,7 +671,7 @@ int msm_camera_register_threaded_irq(struct platform_device *pdev,
rc = -EINVAL;
}
- CDBG("Registered irq for %s[resource - %p]\n", irq_name, irq);
+ CDBG("Registered irq for %s[resource - %pK]\n", irq_name, irq);
return rc;
}
@@ -703,7 +703,7 @@ int msm_camera_unregister_irq(struct platform_device *pdev,
return -EINVAL;
}
- CDBG("Un Registering irq for [resource - %p]\n", irq);
+ CDBG("Un Registering irq for [resource - %pK]\n", irq);
devm_free_irq(&pdev->dev, irq->start, dev_id);
return 0;
@@ -730,7 +730,7 @@ void __iomem *msm_camera_get_reg_base(struct platform_device *pdev,
}
if (reserve_mem) {
- CDBG("device:%p, mem : %p, size : %d\n",
+ CDBG("device:%pK, mem : %pK, size : %d\n",
&pdev->dev, mem, (int)resource_size(mem));
if (!devm_request_mem_region(&pdev->dev, mem->start,
resource_size(mem),
@@ -749,7 +749,7 @@ void __iomem *msm_camera_get_reg_base(struct platform_device *pdev,
return NULL;
}
- CDBG("base : %p\n", base);
+ CDBG("base : %pK\n", base);
return base;
}
EXPORT_SYMBOL(msm_camera_get_reg_base);
@@ -793,7 +793,7 @@ int msm_camera_put_reg_base(struct platform_device *pdev,
pr_err("err: mem resource %s not found\n", device_name);
return -EINVAL;
}
- CDBG("mem : %p, size : %d\n", mem, (int)resource_size(mem));
+ CDBG("mem : %pK, size : %d\n", mem, (int)resource_size(mem));
devm_iounmap(&pdev->dev, base);
if (reserve_mem)
diff --git a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
index f978f97d7895..51a9ea85d1f3 100644
--- a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
+++ b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
@@ -27,7 +27,7 @@
void msm_camera_io_w(u32 data, void __iomem *addr)
{
- CDBG("%s: 0x%p %08x\n", __func__, (addr), (data));
+ CDBG("%s: 0x%pK %08x\n", __func__, (addr), (data));
writel_relaxed((data), (addr));
}
@@ -43,7 +43,7 @@ int32_t msm_camera_io_w_block(const u32 *addr, void __iomem *base,
return -EINVAL;
for (i = 0; i < len; i++) {
- CDBG("%s: len =%d val=%x base =%p\n", __func__,
+ CDBG("%s: len =%d val=%x base =%pK\n", __func__,
len, addr[i], base);
writel_relaxed(addr[i], base);
}
@@ -62,7 +62,7 @@ int32_t msm_camera_io_w_reg_block(const u32 *addr, void __iomem *base,
return -EINVAL;
for (i = 0; i < len; i = i + 2) {
- CDBG("%s: len =%d val=%x base =%p reg=%x\n", __func__,
+ CDBG("%s: len =%d val=%x base =%pK reg=%x\n", __func__,
len, addr[i + 1], base, addr[i]);
writel_relaxed(addr[i + 1], base + addr[i]);
}
@@ -71,7 +71,7 @@ int32_t msm_camera_io_w_reg_block(const u32 *addr, void __iomem *base,
void msm_camera_io_w_mb(u32 data, void __iomem *addr)
{
- CDBG("%s: 0x%p %08x\n", __func__, (addr), (data));
+ CDBG("%s: 0x%pK %08x\n", __func__, (addr), (data));
/* ensure write is done */
wmb();
writel_relaxed((data), (addr));
@@ -89,7 +89,7 @@ int32_t msm_camera_io_w_mb_block(const u32 *addr, void __iomem *base, u32 len)
for (i = 0; i < len; i++) {
/* ensure write is done */
wmb();
- CDBG("%s: len =%d val=%x base =%p\n", __func__,
+ CDBG("%s: len =%d val=%x base =%pK\n", __func__,
len, addr[i], base);
writel_relaxed(addr[i], base);
}
@@ -102,7 +102,7 @@ u32 msm_camera_io_r(void __iomem *addr)
{
uint32_t data = readl_relaxed(addr);
- CDBG("%s: 0x%p %08x\n", __func__, (addr), (data));
+ CDBG("%s: 0x%pK %08x\n", __func__, (addr), (data));
return data;
}
@@ -114,7 +114,7 @@ u32 msm_camera_io_r_mb(void __iomem *addr)
data = readl_relaxed(addr);
/* ensure read is done */
rmb();
- CDBG("%s: 0x%p %08x\n", __func__, (addr), (data));
+ CDBG("%s: 0x%pK %08x\n", __func__, (addr), (data));
return data;
}
@@ -180,7 +180,7 @@ void msm_camera_io_dump(void __iomem *addr, int size, int enable)
u32 *p = (u32 *) addr;
u32 data;
- CDBG("%s: addr=%p size=%d\n", __func__, addr, size);
+ CDBG("%s: addr=%pK size=%d\n", __func__, addr, size);
if (!p || (size <= 0) || !enable)
return;
@@ -216,12 +216,12 @@ void msm_camera_io_dump_wstring_base(void __iomem *addr,
{
int i, u = sizeof(struct msm_cam_dump_string_info);
- pr_debug("%s: addr=%p data=%p size=%d u=%d, cnt=%d\n", __func__,
+ pr_debug("%s: addr=%pK data=%pK size=%d u=%d, cnt=%d\n", __func__,
addr, dump_data, size, u,
(size/u));
if (!addr || (size <= 0) || !dump_data) {
- pr_err("%s: addr=%p data=%p size=%d\n", __func__,
+ pr_err("%s: addr=%pK data=%pK size=%d\n", __func__,
addr, dump_data, size);
return;
}
@@ -233,7 +233,7 @@ void msm_camera_io_dump_wstring_base(void __iomem *addr,
void msm_camera_io_memcpy(void __iomem *dest_addr,
void __iomem *src_addr, u32 len)
{
- CDBG("%s: %p %p %d\n", __func__, dest_addr, src_addr, len);
+ CDBG("%s: %pK %pK %d\n", __func__, dest_addr, src_addr, len);
msm_camera_io_memcpy_toio(dest_addr, src_addr, len / 4);
}
@@ -728,7 +728,7 @@ int msm_camera_request_gpio_table(struct gpio *gpio_tbl, uint8_t size,
int rc = 0, i = 0, err = 0;
if (!gpio_tbl || !size) {
- pr_err("%s:%d invalid gpio_tbl %p / size %d\n", __func__,
+ pr_err("%s:%d invalid gpio_tbl %pK / size %d\n", __func__,
__LINE__, gpio_tbl, size);
return -EINVAL;
}
@@ -772,7 +772,7 @@ int msm_camera_get_dt_reg_settings(struct device_node *of_node,
unsigned int cnt;
if (!of_node || !dt_prop_name || !size || !reg_s) {
- pr_err("%s: Error invalid args %p:%p:%p:%p\n",
+ pr_err("%s: Error invalid args %pK:%pK:%pK:%pK\n",
__func__, size, reg_s, of_node, dt_prop_name);
return -EINVAL;
}
diff --git a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h
index 993203bb9dff..4155eb8a6faf 100644
--- a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h
+++ b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h
@@ -252,6 +252,7 @@ struct msm_fd_device {
struct work_struct work;
struct completion hw_halt_completion;
int recovery_mode;
+ uint32_t clk_rate_idx;
};
#endif /* __MSM_FD_DEV_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/fd/msm_fd_hw.c b/drivers/media/platform/msm/camera_v2/fd/msm_fd_hw.c
index 24683441d5ed..a20f40a0969f 100644
--- a/drivers/media/platform/msm/camera_v2/fd/msm_fd_hw.c
+++ b/drivers/media/platform/msm/camera_v2/fd/msm_fd_hw.c
@@ -669,7 +669,7 @@ int32_t msm_fd_hw_set_dt_parms_by_name(struct msm_fd_device *fd,
dt_reg_settings[i + MSM_FD_REG_ADDR_OFFSET_IDX],
dt_reg_settings[i + MSM_FD_REG_VALUE_IDX] &
dt_reg_settings[i + MSM_FD_REG_MASK_IDX]);
- pr_debug("%s:%d] %p %08x\n", __func__, __LINE__,
+ pr_debug("%s:%d] %pK %08x\n", __func__, __LINE__,
fd->iomem_base[base_idx] +
dt_reg_settings[i + MSM_FD_REG_ADDR_OFFSET_IDX],
dt_reg_settings[i + MSM_FD_REG_VALUE_IDX] &
@@ -822,6 +822,45 @@ static int msm_fd_hw_set_clock_rate_idx(struct msm_fd_device *fd,
return 0;
}
+
+/**
+ * msm_fd_hw_update_settings() - API to set clock rate and bus settings
+ * @fd: Pointer to fd device.
+ * @buf: fd buffer
+ */
+static int msm_fd_hw_update_settings(struct msm_fd_device *fd,
+ struct msm_fd_buffer *buf)
+{
+ int ret = 0;
+ uint32_t clk_rate_idx;
+
+ if (!buf)
+ return 0;
+
+ clk_rate_idx = buf->settings.speed;
+ if (fd->clk_rate_idx == clk_rate_idx)
+ return 0;
+
+ if (fd->bus_client) {
+ ret = msm_fd_hw_bus_request(fd, clk_rate_idx);
+ if (ret < 0) {
+ dev_err(fd->dev, "Fail bus scale update %d\n", ret);
+ return -EINVAL;
+ }
+ }
+
+ ret = msm_fd_hw_set_clock_rate_idx(fd, clk_rate_idx);
+ if (ret < 0) {
+ dev_err(fd->dev, "Fail to set clock rate idx\n");
+ goto end;
+ }
+ dev_dbg(fd->dev, "set clk %d %d", fd->clk_rate_idx, clk_rate_idx);
+ fd->clk_rate_idx = clk_rate_idx;
+
+end:
+ return ret;
+}
+
/*
* msm_fd_hw_get - Get fd hw for performing any hw operation.
* @fd: Pointer to fd device.
@@ -868,6 +907,8 @@ int msm_fd_hw_get(struct msm_fd_device *fd, unsigned int clock_rate_idx)
ret = msm_fd_hw_set_dt_parms(fd);
if (ret < 0)
goto error_set_dt;
+
+ fd->clk_rate_idx = clock_rate_idx;
}
fd->ref_count++;
@@ -1228,6 +1269,8 @@ int msm_fd_hw_schedule_and_start(struct msm_fd_device *fd)
spin_unlock(&fd->slock);
+ msm_fd_hw_update_settings(fd, buf);
+
return 0;
}
@@ -1266,5 +1309,7 @@ int msm_fd_hw_schedule_next_buffer(struct msm_fd_device *fd)
}
spin_unlock(&fd->slock);
+ msm_fd_hw_update_settings(fd, buf);
+
return 0;
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 3331f0d4c340..94e974529e56 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -62,13 +62,13 @@ static int msm_buf_check_head_sanity(struct msm_isp_bufq *bufq)
}
if (prev->next != &bufq->head) {
- pr_err("%s: Error! head prev->next is %p should be %p\n",
+ pr_err("%s: Error! head prev->next is %pK should be %pK\n",
__func__, prev->next, &bufq->head);
return -EINVAL;
}
if (next->prev != &bufq->head) {
- pr_err("%s: Error! head next->prev is %p should be %p\n",
+ pr_err("%s: Error! head next->prev is %pK should be %pK\n",
__func__, next->prev, &bufq->head);
return -EINVAL;
}
@@ -228,7 +228,7 @@ static void msm_isp_unprepare_v4l2_buf(
struct msm_isp_bufq *bufq = NULL;
if (!buf_mgr || !buf_info) {
- pr_err("%s: NULL ptr %p %p\n", __func__,
+ pr_err("%s: NULL ptr %pK %pK\n", __func__,
buf_mgr, buf_info);
return;
}
@@ -255,7 +255,7 @@ static int msm_isp_map_buf(struct msm_isp_buf_mgr *buf_mgr,
int ret;
if (!buf_mgr || !mapped_info) {
- pr_err_ratelimited("%s: %d] NULL ptr buf_mgr %p mapped_info %p\n",
+ pr_err_ratelimited("%s: %d] NULL ptr buf_mgr %pK mapped_info %pK\n",
__func__, __LINE__, buf_mgr, mapped_info);
return -EINVAL;
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index 354fda32ff3b..eebcecc7bbe6 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -616,6 +616,7 @@ struct dual_vfe_resource {
struct msm_vfe_stats_shared_data *stats_data[MAX_VFE];
struct msm_vfe_axi_shared_data *axi_data[MAX_VFE];
uint32_t wm_reload_mask[MAX_VFE];
+ uint32_t epoch_sync_mask;
};
struct master_slave_resource_info {
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c
index e1e579bc292c..f15f234c007e 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c
@@ -920,7 +920,7 @@ static int msm_vfe46_start_fetch_engine(struct vfe_device *vfe_dev,
rc = vfe_dev->buf_mgr->ops->get_buf_by_index(
vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf);
if (rc < 0 || !buf) {
- pr_err("%s: No fetch buffer rc= %d buf= %p\n",
+ pr_err("%s: No fetch buffer rc= %d buf= %pK\n",
__func__, rc, buf);
return -EINVAL;
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
index ea3c8f71912b..ebf38dd387d6 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
@@ -1058,7 +1058,7 @@ static int msm_vfe47_start_fetch_engine(struct vfe_device *vfe_dev,
rc = vfe_dev->buf_mgr->ops->get_buf_by_index(
vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf);
if (rc < 0 || !buf) {
- pr_err("%s: No fetch buffer rc= %d buf= %p\n",
+ pr_err("%s: No fetch buffer rc= %d buf= %pK\n",
__func__, rc, buf);
return -EINVAL;
}
@@ -1443,6 +1443,8 @@ static void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev,
if ((vfe_dev->hvx_cmd > HVX_DISABLE) &&
(vfe_dev->hvx_cmd <= HVX_ROUND_TRIP))
msm_vfe47_configure_hvx(vfe_dev, 1);
+ else
+ msm_vfe47_configure_hvx(vfe_dev, 0);
bus_en =
((vfe_dev->axi_data.
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index c98b8ad6306b..a5952a5b9b0a 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -146,6 +146,14 @@ int msm_isp_validate_axi_request(struct msm_vfe_axi_shared_data *axi_data,
case V4L2_PIX_FMT_SGBRG10:
case V4L2_PIX_FMT_SGRBG10:
case V4L2_PIX_FMT_SRGGB10:
+ case V4L2_PIX_FMT_SBGGR10DPCM6:
+ case V4L2_PIX_FMT_SGBRG10DPCM6:
+ case V4L2_PIX_FMT_SGRBG10DPCM6:
+ case V4L2_PIX_FMT_SRGGB10DPCM6:
+ case V4L2_PIX_FMT_SBGGR10DPCM8:
+ case V4L2_PIX_FMT_SGBRG10DPCM8:
+ case V4L2_PIX_FMT_SGRBG10DPCM8:
+ case V4L2_PIX_FMT_SRGGB10DPCM8:
case V4L2_PIX_FMT_SBGGR12:
case V4L2_PIX_FMT_SGBRG12:
case V4L2_PIX_FMT_SGRBG12:
@@ -272,6 +280,14 @@ static uint32_t msm_isp_axi_get_plane_size(
case V4L2_PIX_FMT_SGBRG10:
case V4L2_PIX_FMT_SGRBG10:
case V4L2_PIX_FMT_SRGGB10:
+ case V4L2_PIX_FMT_SBGGR10DPCM6:
+ case V4L2_PIX_FMT_SGBRG10DPCM6:
+ case V4L2_PIX_FMT_SGRBG10DPCM6:
+ case V4L2_PIX_FMT_SRGGB10DPCM6:
+ case V4L2_PIX_FMT_SBGGR10DPCM8:
+ case V4L2_PIX_FMT_SGBRG10DPCM8:
+ case V4L2_PIX_FMT_SGRBG10DPCM8:
+ case V4L2_PIX_FMT_SRGGB10DPCM8:
case V4L2_PIX_FMT_QBGGR10:
case V4L2_PIX_FMT_QGBRG10:
case V4L2_PIX_FMT_QGRBG10:
@@ -528,6 +544,89 @@ static void msm_isp_cfg_framedrop_reg(struct vfe_device *vfe_dev,
}
/**
+ * msm_isp_check_epoch_status() - check the epock signal for framedrop
+ *
+ * @vfe_dev: The h/w on which the epoch signel is reveived
+ * @frame_src: The source of the epoch signal for this frame
+ *
+ * For dual vfe case and pixel stream, if both vfe's epoch signal is
+ * received, this function will return success.
+ * It will also return the vfe1 for further process
+ * For none dual VFE stream or none pixl source, this
+ * funciton will just return success.
+ *
+ * Returns 1 - epoch received is complete.
+ * 0 - epoch reveived is not complete.
+ */
+static int msm_isp_check_epoch_status(struct vfe_device **vfe_dev,
+ enum msm_vfe_input_src frame_src)
+{
+ struct vfe_device *vfe_dev_cur = *vfe_dev;
+ struct vfe_device *vfe_dev_other = NULL;
+ uint32_t vfe_id_other = 0;
+ uint32_t vfe_id_cur = 0;
+ uint32_t epoch_mask = 0;
+ unsigned long flags;
+ int completed = 0;
+
+ spin_lock_irqsave(
+ &vfe_dev_cur->common_data->common_dev_data_lock, flags);
+
+ if (vfe_dev_cur->is_split &&
+ frame_src == VFE_PIX_0) {
+ if (vfe_dev_cur->pdev->id == ISP_VFE0) {
+ vfe_id_cur = ISP_VFE0;
+ vfe_id_other = ISP_VFE1;
+ } else {
+ vfe_id_cur = ISP_VFE1;
+ vfe_id_other = ISP_VFE0;
+ }
+ vfe_dev_other = vfe_dev_cur->common_data->dual_vfe_res->
+ vfe_dev[vfe_id_other];
+
+ if (vfe_dev_cur->common_data->dual_vfe_res->
+ epoch_sync_mask & (1 << vfe_id_cur)) {
+ /* serious scheduling delay */
+ pr_err("Missing epoch: vfe %d, epoch mask 0x%x\n",
+ vfe_dev_cur->pdev->id,
+ vfe_dev_cur->common_data->dual_vfe_res->
+ epoch_sync_mask);
+ goto fatal;
+ }
+
+ vfe_dev_cur->common_data->dual_vfe_res->
+ epoch_sync_mask |= (1 << vfe_id_cur);
+
+ epoch_mask = (1 << vfe_id_cur) | (1 << vfe_id_other);
+ if ((vfe_dev_cur->common_data->dual_vfe_res->
+ epoch_sync_mask & epoch_mask) == epoch_mask) {
+
+ if (vfe_id_other == ISP_VFE0)
+ *vfe_dev = vfe_dev_cur;
+ else
+ *vfe_dev = vfe_dev_other;
+
+ vfe_dev_cur->common_data->dual_vfe_res->
+ epoch_sync_mask &= ~epoch_mask;
+ completed = 1;
+ }
+ } else
+ completed = 1;
+
+ spin_unlock_irqrestore(
+ &vfe_dev_cur->common_data->common_dev_data_lock, flags);
+
+ return completed;
+fatal:
+ spin_unlock_irqrestore(
+ &vfe_dev_cur->common_data->common_dev_data_lock, flags);
+ /* new error event code will be added later */
+ msm_isp_halt_send_error(vfe_dev_cur, ISP_EVENT_PING_PONG_MISMATCH);
+ return 0;
+}
+
+
+/**
* msm_isp_update_framedrop_reg() - Update frame period pattern on h/w
* @vfe_dev: The h/w on which the perion pattern is updated.
* @frame_src: Input source.
@@ -542,10 +641,15 @@ void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev,
enum msm_vfe_input_src frame_src)
{
int i;
- struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+ struct msm_vfe_axi_shared_data *axi_data = NULL;
struct msm_vfe_axi_stream *stream_info;
unsigned long flags;
+ if (msm_isp_check_epoch_status(&vfe_dev, frame_src) != 1)
+ return;
+
+ axi_data = &vfe_dev->axi_data;
+
for (i = 0; i < VFE_AXI_SRC_MAX; i++) {
if (SRC_TO_INTF(axi_data->stream_info[i].stream_src) !=
frame_src) {
@@ -621,7 +725,7 @@ void msm_isp_check_for_output_error(struct vfe_device *vfe_dev,
int i;
if (!vfe_dev || !sof_info) {
- pr_err("%s %d failed: vfe_dev %p sof_info %p\n", __func__,
+ pr_err("%s %d failed: vfe_dev %pK sof_info %pK\n", __func__,
__LINE__, vfe_dev, sof_info);
return;
}
@@ -1180,7 +1284,7 @@ static int msm_isp_axi_stream_enable_cfg(
!dual_vfe_res->axi_data[ISP_VFE0] ||
!dual_vfe_res->vfe_base[ISP_VFE1] ||
!dual_vfe_res->axi_data[ISP_VFE1]) {
- pr_err("%s:%d failed vfe0 %p %p vfe %p %p\n",
+ pr_err("%s:%d failed vfe0 %pK %pK vfe %pK %pK\n",
__func__, __LINE__,
dual_vfe_res->vfe_base[ISP_VFE0],
dual_vfe_res->axi_data[ISP_VFE0],
@@ -1354,19 +1458,9 @@ void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev,
cfg_wm_reg(vfe_dev, stream_info, j);
/*Resume AXI*/
stream_info->state = RESUME_PENDING;
- if (vfe_dev->is_split) {
- msm_isp_update_dual_HW_axi(vfe_dev,
- stream_info);
- } else {
- msm_isp_axi_stream_enable_cfg(
- vfe_dev,
- &axi_data->stream_info[i], 1);
- stream_info->state = RESUMING;
- }
+ msm_isp_update_dual_HW_axi(vfe_dev, stream_info);
} else if (stream_info->state == RESUMING) {
- stream_info->runtime_output_format =
- stream_info->output_format;
- stream_info->state = ACTIVE;
+ msm_isp_update_dual_HW_axi(vfe_dev, stream_info);
}
spin_unlock_irqrestore(&stream_info->lock, flags);
}
@@ -1565,7 +1659,7 @@ static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
!dual_vfe_res->axi_data[ISP_VFE0] ||
!dual_vfe_res->vfe_base[ISP_VFE1] ||
!dual_vfe_res->axi_data[ISP_VFE1]) {
- pr_err("%s:%d failed vfe0 %p %p vfe %p %p\n",
+ pr_err("%s:%d failed vfe0 %pK %pK vfe %pK %pK\n",
__func__, __LINE__,
dual_vfe_res->vfe_base[ISP_VFE0],
dual_vfe_res->axi_data[ISP_VFE0],
@@ -1846,7 +1940,7 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev,
uint32_t pingpong_bit;
if (!vfe_dev || !stream_info || !ts || !sof_info) {
- pr_err("%s %d vfe_dev %p stream_info %p ts %p op_info %p\n",
+ pr_err("%s %d vfe_dev %pK stream_info %pK ts %pK op_info %pK\n",
__func__, __LINE__, vfe_dev, stream_info, ts,
sof_info);
return -EINVAL;
@@ -1902,6 +1996,13 @@ static void msm_isp_get_camif_update_state_and_halt(
pix_stream_cnt++;
}
+ if (vfe_dev->axi_data.num_active_stream == stream_cfg_cmd->num_streams
+ && (stream_cfg_cmd->cmd == STOP_STREAM ||
+ stream_cfg_cmd->cmd == STOP_IMMEDIATELY))
+ *halt = 1;
+ else
+ *halt = 0;
+
if ((pix_stream_cnt) &&
(axi_data->src_info[VFE_PIX_0].input_mux != EXTERNAL_READ)) {
if (cur_pix_stream_cnt == 0 && pix_stream_cnt &&
@@ -1909,24 +2010,17 @@ static void msm_isp_get_camif_update_state_and_halt(
*camif_update = ENABLE_CAMIF;
else if (cur_pix_stream_cnt &&
(cur_pix_stream_cnt - pix_stream_cnt) == 0 &&
- stream_cfg_cmd->cmd == STOP_STREAM)
- *camif_update = DISABLE_CAMIF;
- else if (cur_pix_stream_cnt &&
- (cur_pix_stream_cnt - pix_stream_cnt) == 0 &&
- stream_cfg_cmd->cmd == STOP_IMMEDIATELY)
- *camif_update = DISABLE_CAMIF_IMMEDIATELY;
+ (stream_cfg_cmd->cmd == STOP_STREAM ||
+ stream_cfg_cmd->cmd == STOP_IMMEDIATELY)) {
+ if (*halt)
+ *camif_update = DISABLE_CAMIF_IMMEDIATELY;
+ else
+ *camif_update = DISABLE_CAMIF;
+ }
else
*camif_update = NO_UPDATE;
} else
*camif_update = NO_UPDATE;
-
- if (vfe_dev->axi_data.num_active_stream == stream_cfg_cmd->num_streams
- && (stream_cfg_cmd->cmd == STOP_STREAM ||
- stream_cfg_cmd->cmd == STOP_IMMEDIATELY))
- *halt = 1;
- else
- *halt = 0;
-
}
static void msm_isp_update_camif_output_count(
@@ -2136,7 +2230,7 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
unsigned long flags;
if (!reset_cmd) {
- pr_err("%s: NULL pointer reset cmd %p\n", __func__, reset_cmd);
+ pr_err("%s: NULL pointer reset cmd %pK\n", __func__, reset_cmd);
rc = -1;
return rc;
}
@@ -2418,28 +2512,54 @@ static int msm_isp_update_dual_HW_axi(struct vfe_device *vfe_dev,
}
dual_vfe_res = vfe_dev->common_data->dual_vfe_res;
+ if (vfe_dev->is_split) {
+ if (!dual_vfe_res->vfe_dev[ISP_VFE0] ||
+ !dual_vfe_res->vfe_dev[ISP_VFE1] ||
+ !dual_vfe_res->axi_data[ISP_VFE0] ||
+ !dual_vfe_res->axi_data[ISP_VFE1]) {
+ pr_err("%s: Error in dual vfe resource\n", __func__);
+ rc = -EINVAL;
+ } else {
+ if (stream_info->state == RESUME_PENDING &&
+ (dual_vfe_res->axi_data[!vfe_dev->pdev->id]->
+ stream_info[stream_idx].state ==
+ RESUME_PENDING)) {
+ /* Update the AXI only after both ISPs receiving
+ the Reg update interrupt*/
+ for (vfe_id = 0; vfe_id < MAX_VFE; vfe_id++) {
+ rc = msm_isp_axi_stream_enable_cfg(
+ dual_vfe_res->vfe_dev[vfe_id],
+ &dual_vfe_res->
+ axi_data[vfe_id]->
+ stream_info[stream_idx], 1);
+ dual_vfe_res->axi_data[vfe_id]->
+ stream_info[stream_idx].state =
+ RESUMING;
+ }
+ } else if (stream_info->state == RESUMING &&
+ (dual_vfe_res->axi_data[!vfe_dev->pdev->id]->
+ stream_info[stream_idx].state == RESUMING)) {
+ for (vfe_id = 0; vfe_id < MAX_VFE; vfe_id++) {
+ dual_vfe_res->axi_data[vfe_id]->
+ stream_info[stream_idx].
+ runtime_output_format =
+ stream_info->output_format;
+ dual_vfe_res->axi_data[vfe_id]->
+ stream_info[stream_idx].state =
+ ACTIVE;
+ }
+ }
- if (!dual_vfe_res->vfe_dev[ISP_VFE0] ||
- !dual_vfe_res->vfe_dev[ISP_VFE1] ||
- !dual_vfe_res->axi_data[ISP_VFE0] ||
- !dual_vfe_res->axi_data[ISP_VFE1]) {
- pr_err("%s: Error in dual vfe resource\n", __func__);
- rc = -EINVAL;
+ }
} else {
- if (stream_info->state == RESUME_PENDING &&
- (dual_vfe_res->axi_data[!vfe_dev->pdev->id]->
- stream_info[stream_idx].state == RESUME_PENDING)) {
- /* Update the AXI only after both ISPs receiving the
- Reg update interrupt*/
- for (vfe_id = 0; vfe_id < MAX_VFE; vfe_id++) {
- rc = msm_isp_axi_stream_enable_cfg(
- dual_vfe_res->vfe_dev[vfe_id],
- &dual_vfe_res->axi_data[vfe_id]->
- stream_info[stream_idx], 1);
- dual_vfe_res->axi_data[vfe_id]->
- stream_info[stream_idx].state =
- RESUMING;
- }
+ if (stream_info->state == RESUME_PENDING) {
+ msm_isp_axi_stream_enable_cfg(
+ vfe_dev, stream_info, 0);
+ stream_info->state = RESUMING;
+ } else if (stream_info->state == RESUMING) {
+ stream_info->runtime_output_format =
+ stream_info->output_format;
+ stream_info->state = ACTIVE;
}
}
return rc;
@@ -2549,6 +2669,7 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev,
vfe_dev->hw_info->vfe_ops.core_ops.
update_camif_state(vfe_dev, camif_update);
vfe_dev->axi_data.camif_state = CAMIF_ENABLE;
+ vfe_dev->common_data->dual_vfe_res->epoch_sync_mask = 0;
}
if (wait_for_complete) {
@@ -2610,34 +2731,20 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev,
wait_for_complete_for_this_stream = 0;
stream_info->state = STOP_PENDING;
- ISP_DBG("Stop axi Stream 0x%x\n", stream_info->stream_id);
- if (stream_info->stream_src == CAMIF_RAW ||
- stream_info->stream_src == IDEAL_RAW) {
- /* We dont get reg update IRQ for raw snapshot
- * so frame skip cant be ocnfigured
- */
- if ((camif_update != DISABLE_CAMIF_IMMEDIATELY) &&
- (!ext_read))
- wait_for_complete_for_this_stream = 1;
-
- } else if (stream_info->stream_type == BURST_STREAM &&
- stream_info->runtime_num_burst_capture == 0) {
- /* Configure AXI writemasters to stop immediately
- * since for burst case, write masters already skip
- * all frames.
- */
- if (stream_info->stream_src == RDI_INTF_0 ||
- stream_info->stream_src == RDI_INTF_1 ||
- stream_info->stream_src == RDI_INTF_2)
- wait_for_complete_for_this_stream = 1;
- } else {
- if ((camif_update != DISABLE_CAMIF_IMMEDIATELY) &&
- !halt && (!ext_read))
- wait_for_complete_for_this_stream = 1;
- }
- ISP_DBG("%s: vfe_dev %d camif_update %d halt %d wait %d\n",
- __func__, vfe_dev->pdev->id, camif_update, halt,
+
+ if (!halt && !ext_read &&
+ !(stream_info->stream_type == BURST_STREAM &&
+ stream_info->runtime_num_burst_capture == 0))
+ wait_for_complete_for_this_stream = 1;
+
+ ISP_DBG("%s: stream 0x%x, vfe %d camif %d halt %d wait %d\n",
+ __func__,
+ stream_info->stream_id,
+ vfe_dev->pdev->id,
+ camif_update,
+ halt,
wait_for_complete_for_this_stream);
+
intf = SRC_TO_INTF(stream_info->stream_src);
if (!wait_for_complete_for_this_stream ||
stream_info->state == INACTIVE ||
@@ -2821,7 +2928,7 @@ static int msm_isp_return_empty_buffer(struct vfe_device *vfe_dev,
struct msm_isp_timestamp timestamp;
if (!vfe_dev || !stream_info) {
- pr_err("%s %d failed: vfe_dev %p stream_info %p\n", __func__,
+ pr_err("%s %d failed: vfe_dev %pK stream_info %pK\n", __func__,
__LINE__, vfe_dev, stream_info);
return -EINVAL;
}
@@ -2900,7 +3007,7 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
bool dual_vfe = false;
if (!vfe_dev || !stream_info) {
- pr_err("%s %d failed: vfe_dev %p stream_info %p\n", __func__,
+ pr_err("%s %d failed: vfe_dev %pK stream_info %pK\n", __func__,
__LINE__, vfe_dev, stream_info);
return -EINVAL;
}
@@ -3552,7 +3659,7 @@ void msm_isp_axi_disable_all_wm(struct vfe_device *vfe_dev)
int i, j;
if (!vfe_dev || !axi_data) {
- pr_err("%s: error %p %p\n", __func__, vfe_dev, axi_data);
+ pr_err("%s: error %pK %pK\n", __func__, vfe_dev, axi_data);
return;
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
index 7eaffad3f9ad..03c587e2ede1 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
@@ -88,8 +88,9 @@ static int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev,
!dual_vfe_res->stats_data[ISP_VFE0] ||
!dual_vfe_res->vfe_base[ISP_VFE1] ||
!dual_vfe_res->stats_data[ISP_VFE1]) {
- pr_err("%s:%d error vfe0 %p %p vfe1 %p %p\n", __func__,
- __LINE__, dual_vfe_res->vfe_base[ISP_VFE0],
+ pr_err("%s:%d error vfe0 %pK %pK vfe1 %pK %pK\n",
+ __func__, __LINE__,
+ dual_vfe_res->vfe_base[ISP_VFE0],
dual_vfe_res->stats_data[ISP_VFE0],
dual_vfe_res->vfe_base[ISP_VFE1],
dual_vfe_res->stats_data[ISP_VFE1]);
@@ -156,7 +157,7 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev,
uint32_t stats_idx;
if (!vfe_dev || !ts || !buf_event || !stream_info) {
- pr_err("%s:%d failed: invalid params %p %p %p %p\n",
+ pr_err("%s:%d failed: invalid params %pK %pK %pK %pK\n",
__func__, __LINE__, vfe_dev, ts, buf_event,
stream_info);
return -EINVAL;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index 8a6c395e9812..dc209d744054 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -468,14 +468,14 @@ static int msm_isp_get_max_clk_rate(struct vfe_device *vfe_dev, long *rate)
long round_rate = 0;
if (!vfe_dev || !rate) {
- pr_err("%s:%d failed: vfe_dev %p rate %p\n", __func__, __LINE__,
- vfe_dev, rate);
+ pr_err("%s:%d failed: vfe_dev %pK rate %pK\n", __func__,
+ __LINE__, vfe_dev, rate);
return -EINVAL;
}
*rate = 0;
if (!vfe_dev->hw_info) {
- pr_err("%s:%d failed: vfe_dev->hw_info %p\n", __func__,
+ pr_err("%s:%d failed: vfe_dev->hw_info %pK\n", __func__,
__LINE__, vfe_dev->hw_info);
return -EINVAL;
}
@@ -505,13 +505,13 @@ static int msm_isp_get_clk_rates(struct vfe_device *vfe_dev,
int32_t rc = 0;
uint32_t svs = 0, nominal = 0, turbo = 0;
if (!vfe_dev || !rates) {
- pr_err("%s:%d failed: vfe_dev %p rates %p\n", __func__,
+ pr_err("%s:%d failed: vfe_dev %pK rates %pK\n", __func__,
__LINE__, vfe_dev, rates);
return -EINVAL;
}
if (!vfe_dev->pdev) {
- pr_err("%s:%d failed: vfe_dev->pdev %p\n", __func__,
+ pr_err("%s:%d failed: vfe_dev->pdev %pK\n", __func__,
__LINE__, vfe_dev->pdev);
return -EINVAL;
}
@@ -519,7 +519,7 @@ static int msm_isp_get_clk_rates(struct vfe_device *vfe_dev,
of_node = vfe_dev->pdev->dev.of_node;
if (!of_node) {
- pr_err("%s %d failed: of_node = %p\n", __func__,
+ pr_err("%s %d failed: of_node = %pK\n", __func__,
__LINE__, of_node);
return -EINVAL;
}
@@ -625,9 +625,7 @@ static int msm_isp_cfg_pix(struct vfe_device *vfe_dev,
}
pix_cfg = &input_cfg->d.pix_cfg;
- if ((pix_cfg->hvx_cmd > HVX_DISABLE) &&
- (pix_cfg->hvx_cmd <= HVX_ROUND_TRIP))
- vfe_dev->hvx_cmd = pix_cfg->hvx_cmd;
+ vfe_dev->hvx_cmd = pix_cfg->hvx_cmd;
vfe_dev->is_split = input_cfg->d.pix_cfg.is_split;
vfe_dev->axi_data.src_info[VFE_PIX_0].pixel_clock =
@@ -730,7 +728,7 @@ static int msm_isp_set_dual_HW_master_slave_mode(
unsigned long flags;
if (!vfe_dev || !arg) {
- pr_err("%s: Error! Invalid input vfe_dev %p arg %p\n",
+ pr_err("%s: Error! Invalid input vfe_dev %pK arg %pK\n",
__func__, vfe_dev, arg);
return -EINVAL;
}
@@ -821,7 +819,7 @@ static int msm_isp_proc_cmd_list_unlocked(struct vfe_device *vfe_dev, void *arg)
struct msm_vfe_cfg_cmd_list cmd, cmd_next;
if (!vfe_dev || !arg) {
- pr_err("%s:%d failed: vfe_dev %p arg %p", __func__, __LINE__,
+ pr_err("%s:%d failed: vfe_dev %pK arg %pK", __func__, __LINE__,
vfe_dev, arg);
return -EINVAL;
}
@@ -891,7 +889,7 @@ static int msm_isp_proc_cmd_list_compat(struct vfe_device *vfe_dev, void *arg)
struct msm_vfe_cfg_cmd2 current_cmd;
if (!vfe_dev || !arg) {
- pr_err("%s:%d failed: vfe_dev %p arg %p", __func__, __LINE__,
+ pr_err("%s:%d failed: vfe_dev %pK arg %pK", __func__, __LINE__,
vfe_dev, arg);
return -EINVAL;
}
@@ -948,10 +946,10 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
if (!vfe_dev || !vfe_dev->vfe_base) {
- pr_err("%s:%d failed: invalid params %p\n",
+ pr_err("%s:%d failed: invalid params %pK\n",
__func__, __LINE__, vfe_dev);
if (vfe_dev)
- pr_err("%s:%d failed %p\n", __func__,
+ pr_err("%s:%d failed %pK\n", __func__,
__LINE__, vfe_dev->vfe_base);
return -EINVAL;
}
@@ -1136,10 +1134,10 @@ static long msm_isp_ioctl_compat(struct v4l2_subdev *sd,
long rc = 0;
if (!vfe_dev || !vfe_dev->vfe_base) {
- pr_err("%s:%d failed: invalid params %p\n",
+ pr_err("%s:%d failed: invalid params %pK\n",
__func__, __LINE__, vfe_dev);
if (vfe_dev)
- pr_err("%s:%d failed %p\n", __func__,
+ pr_err("%s:%d failed %pK\n", __func__,
__LINE__, vfe_dev->vfe_base);
return -EINVAL;
}
@@ -1185,13 +1183,13 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
uint32_t *cfg_data, uint32_t cmd_len)
{
if (!vfe_dev || !reg_cfg_cmd) {
- pr_err("%s:%d failed: vfe_dev %p reg_cfg_cmd %p\n", __func__,
+ pr_err("%s:%d failed: vfe_dev %pK reg_cfg_cmd %pK\n", __func__,
__LINE__, vfe_dev, reg_cfg_cmd);
return -EINVAL;
}
if ((reg_cfg_cmd->cmd_type != VFE_CFG_MASK) &&
(!cfg_data || !cmd_len)) {
- pr_err("%s:%d failed: cmd type %d cfg_data %p cmd_len %d\n",
+ pr_err("%s:%d failed: cmd type %d cfg_data %pK cmd_len %d\n",
__func__, __LINE__, reg_cfg_cmd->cmd_type, cfg_data,
cmd_len);
return -EINVAL;
@@ -1613,6 +1611,14 @@ int msm_isp_cal_word_per_line(uint32_t output_format,
case V4L2_PIX_FMT_SGRBG10:
case V4L2_PIX_FMT_SRGGB10:
case V4L2_PIX_FMT_Y10:
+ case V4L2_PIX_FMT_SBGGR10DPCM6:
+ case V4L2_PIX_FMT_SGBRG10DPCM6:
+ case V4L2_PIX_FMT_SGRBG10DPCM6:
+ case V4L2_PIX_FMT_SRGGB10DPCM6:
+ case V4L2_PIX_FMT_SBGGR10DPCM8:
+ case V4L2_PIX_FMT_SGBRG10DPCM8:
+ case V4L2_PIX_FMT_SGRBG10DPCM8:
+ case V4L2_PIX_FMT_SRGGB10DPCM8:
val = CAL_WORD(pixel_per_line, 5, 32);
break;
case V4L2_PIX_FMT_SBGGR12:
@@ -1690,6 +1696,14 @@ enum msm_isp_pack_fmt msm_isp_get_pack_format(uint32_t output_format)
case V4L2_PIX_FMT_SGBRG10:
case V4L2_PIX_FMT_SGRBG10:
case V4L2_PIX_FMT_SRGGB10:
+ case V4L2_PIX_FMT_SBGGR10DPCM6:
+ case V4L2_PIX_FMT_SGBRG10DPCM6:
+ case V4L2_PIX_FMT_SGRBG10DPCM6:
+ case V4L2_PIX_FMT_SRGGB10DPCM6:
+ case V4L2_PIX_FMT_SBGGR10DPCM8:
+ case V4L2_PIX_FMT_SGBRG10DPCM8:
+ case V4L2_PIX_FMT_SGRBG10DPCM8:
+ case V4L2_PIX_FMT_SRGGB10DPCM8:
case V4L2_PIX_FMT_SBGGR12:
case V4L2_PIX_FMT_SGBRG12:
case V4L2_PIX_FMT_SGRBG12:
@@ -1777,6 +1791,14 @@ int msm_isp_get_bit_per_pixel(uint32_t output_format)
case V4L2_PIX_FMT_SGBRG10:
case V4L2_PIX_FMT_SGRBG10:
case V4L2_PIX_FMT_SRGGB10:
+ case V4L2_PIX_FMT_SBGGR10DPCM6:
+ case V4L2_PIX_FMT_SGBRG10DPCM6:
+ case V4L2_PIX_FMT_SGRBG10DPCM6:
+ case V4L2_PIX_FMT_SRGGB10DPCM6:
+ case V4L2_PIX_FMT_SBGGR10DPCM8:
+ case V4L2_PIX_FMT_SGBRG10DPCM8:
+ case V4L2_PIX_FMT_SGRBG10DPCM8:
+ case V4L2_PIX_FMT_SRGGB10DPCM8:
case V4L2_PIX_FMT_QBGGR10:
case V4L2_PIX_FMT_QGBRG10:
case V4L2_PIX_FMT_QGRBG10:
@@ -1834,7 +1856,7 @@ static int msm_isp_process_iommu_page_fault(struct vfe_device *vfe_dev)
{
int rc = vfe_dev->buf_mgr->pagefault_debug_disable;
- pr_err("%s:%d] VFE%d Handle Page fault! vfe_dev %p\n", __func__,
+ pr_err("%s:%d] VFE%d Handle Page fault! vfe_dev %pK\n", __func__,
__LINE__, vfe_dev->pdev->id, vfe_dev);
msm_isp_halt_send_error(vfe_dev, ISP_EVENT_IOMMU_P_FAULT);
@@ -2026,7 +2048,7 @@ void msm_isp_do_tasklet(unsigned long data)
uint32_t irq_status0, irq_status1, pingpong_status;
if (vfe_dev->vfe_base == NULL || vfe_dev->vfe_open_cnt == 0) {
- ISP_DBG("%s: VFE%d open cnt = %d, device closed(base = %p)\n",
+ ISP_DBG("%s: VFE%d open cnt = %d, device closed(base = %pK)\n",
__func__, vfe_dev->pdev->id, vfe_dev->vfe_open_cnt,
vfe_dev->vfe_base);
return;
@@ -2099,7 +2121,7 @@ static void msm_vfe_iommu_fault_handler(struct iommu_domain *domain,
vfe_dev->page_fault_addr = iova;
if (!vfe_dev->buf_mgr || !vfe_dev->buf_mgr->ops ||
!vfe_dev->axi_data.num_active_stream) {
- pr_err("%s:%d buf_mgr %p active strms %d\n", __func__,
+ pr_err("%s:%d buf_mgr %pK active strms %d\n", __func__,
__LINE__, vfe_dev->buf_mgr,
vfe_dev->axi_data.num_active_stream);
goto end;
@@ -2116,7 +2138,7 @@ static void msm_vfe_iommu_fault_handler(struct iommu_domain *domain,
}
mutex_unlock(&vfe_dev->core_mutex);
} else {
- ISP_DBG("%s:%d] no token received: %p\n",
+ ISP_DBG("%s:%d] no token received: %pK\n",
__func__, __LINE__, token);
goto end;
}
@@ -2131,11 +2153,16 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
ISP_DBG("%s open_cnt %u\n", __func__, vfe_dev->vfe_open_cnt);
- if (vfe_dev->common_data == NULL) {
- pr_err("%s: Error in probe. No common_data\n", __func__);
+ if (vfe_dev->common_data == NULL ||
+ vfe_dev->common_data->dual_vfe_res == NULL) {
+ pr_err("%s: Error in probe. No common_data or dual vfe res\n",
+ __func__);
return -EINVAL;
}
+ if (vfe_dev->pdev->id == ISP_VFE0)
+ vfe_dev->common_data->dual_vfe_res->epoch_sync_mask = 0;
+
mutex_lock(&vfe_dev->realtime_mutex);
mutex_lock(&vfe_dev->core_mutex);
@@ -2146,7 +2173,7 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
}
if (vfe_dev->vfe_base) {
- pr_err("%s:%d invalid params cnt %d base %p\n", __func__,
+ pr_err("%s:%d invalid params cnt %d base %pK\n", __func__,
__LINE__, vfe_dev->vfe_open_cnt, vfe_dev->vfe_base);
vfe_dev->vfe_base = NULL;
}
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index 640379de1ac5..abfae4ffa600 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -1292,7 +1292,7 @@ static int msm_ispif_set_vfe_info(struct ispif_device *ispif,
{
if (!vfe_info || (vfe_info->num_vfe == 0) ||
(vfe_info->num_vfe > ispif->hw_num_isps)) {
- pr_err("Invalid VFE info: %p %d\n", vfe_info,
+ pr_err("Invalid VFE info: %pK %d\n", vfe_info,
(vfe_info ? vfe_info->num_vfe : 0));
return -EINVAL;
}
@@ -1327,7 +1327,7 @@ static int msm_ispif_init(struct ispif_device *ispif,
if (ispif->csid_version >= CSID_VERSION_V30) {
if (!ispif->clk_mux_mem || !ispif->clk_mux_io) {
- pr_err("%s csi clk mux mem %p io %p\n", __func__,
+ pr_err("%s csi clk mux mem %pK io %pK\n", __func__,
ispif->clk_mux_mem, ispif->clk_mux_io);
rc = -ENOMEM;
return rc;
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
index 9339029dbc0f..071ce0a41ed9 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -805,7 +805,7 @@ void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *hw_cmd_p,
new_data = hw_cmd_p->data & hw_cmd_p->mask;
new_data |= old_data;
- JPEG_DBG("%s:%d] %p %08x\n", __func__, __LINE__,
+ JPEG_DBG("%s:%d] %pK %08x\n", __func__, __LINE__,
paddr, new_data);
msm_camera_io_w(new_data, paddr);
}
@@ -908,7 +908,7 @@ void msm_jpeg_io_dump(void *base, int size)
int i;
u32 *p = (u32 *) addr;
u32 data;
- JPEG_DBG_HIGH("%s:%d] %p %d", __func__, __LINE__, addr, size);
+ JPEG_DBG_HIGH("%s:%d] %pK %d", __func__, __LINE__, addr, size);
line_str[0] = '\0';
p_str = line_str;
for (i = 0; i < size/4; i++) {
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
index e076d356d112..266a5a6be2a2 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
@@ -210,7 +210,7 @@ static int32_t msm_jpeg_set_init_dt_parms(struct msm_jpeg_device *pgmn_dev,
return -EINVAL;
}
for (i = 0; i < dt_count; i = i + 2) {
- JPEG_DBG("%s:%d] %p %08x\n",
+ JPEG_DBG("%s:%d] %pK %08x\n",
__func__, __LINE__,
base + dt_reg_settings[i],
dt_reg_settings[i + 1]);
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
index 2e2841aed1a2..d27f56a9ad65 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
@@ -754,7 +754,7 @@ int __msm_jpeg_open(struct msm_jpeg_device *pgmn_dev)
__LINE__, rc);
goto platform_init_fail;
}
- JPEG_DBG("%s:%d] platform resources - base %p, irq %d\n",
+ JPEG_DBG("%s:%d] platform resources - base %pK, irq %d\n",
__func__, __LINE__,
pgmn_dev->base, (int)pgmn_dev->jpeg_irq_res->start);
msm_jpeg_q_cleanup(&pgmn_dev->evt_q);
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c
index 41086936a0b1..f3ceaad21bf5 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c
@@ -93,7 +93,7 @@ static inline u32 msm_jpegdma_hw_read_reg(struct msm_jpegdma_device *dma,
static inline void msm_jpegdma_hw_write_reg(struct msm_jpegdma_device *dma,
enum msm_jpegdma_mem_resources base_idx, u32 reg, u32 value)
{
- pr_debug("%s:%d]%p %08x\n", __func__, __LINE__,
+ pr_debug("%s:%d]%pK %08x\n", __func__, __LINE__,
dma->iomem_base[base_idx] + reg,
value);
msm_camera_io_w(value, dma->iomem_base[base_idx] + reg);
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index f7246f2bc192..0e4a453902aa 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -248,7 +248,7 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id,
break;
}
if (WARN_ON(vb2_buf != vb)) {
- pr_err("VB buffer is INVALID vb=%p, ses_id=%d, str_id=%d\n",
+ pr_err("VB buffer is INVALID vb=%pK, ses_id=%d, str_id=%d\n",
vb, session_id, stream_id);
spin_unlock_irqrestore(&stream->stream_lock, flags);
return -EINVAL;
@@ -290,7 +290,7 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id,
break;
}
if (WARN_ON(vb2_buf != vb)) {
- pr_err("VB buffer is INVALID ses_id=%d, str_id=%d, vb=%p\n",
+ pr_err("VB buffer is INVALID ses_id=%d, str_id=%d, vb=%pK\n",
session_id, stream_id, vb);
spin_unlock_irqrestore(&stream->stream_lock, flags);
return -EINVAL;
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 55fc18e45068..3ee49dba555d 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
@@ -148,7 +148,7 @@ void msm_cpp_vbif_register_error_handler(void *dev,
int (*client_vbif_error_handler)(void *, uint32_t))
{
if (dev == NULL || client >= VBIF_CLIENT_MAX) {
- pr_err("%s: Fail to register handler! dev = %p, client %d\n",
+ pr_err("%s: Fail to register handler! dev = %pK,client %d\n",
__func__, dev, client);
return;
}
@@ -1054,7 +1054,7 @@ int cpp_vbif_error_handler(void *dev, uint32_t vbif_error)
struct cpp_device *cpp_dev = NULL;
if (dev == NULL || vbif_error >= CPP_VBIF_ERROR_MAX) {
- pr_err("failed: dev %p, vbif error %d\n", dev, vbif_error);
+ pr_err("failed: dev %pK,vbif error %d\n", dev, vbif_error);
return -EINVAL;
}
@@ -1083,13 +1083,13 @@ static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
CPP_DBG("E\n");
if (!sd || !fh) {
- pr_err("Wrong input parameters sd %p fh %p!",
+ pr_err("Wrong input parameters sd %pK fh %pK!",
sd, fh);
return -EINVAL;
}
cpp_dev = v4l2_get_subdevdata(sd);
if (!cpp_dev) {
- pr_err("failed: cpp_dev %p\n", cpp_dev);
+ pr_err("failed: cpp_dev %pK\n", cpp_dev);
return -EINVAL;
}
mutex_lock(&cpp_dev->mutex);
@@ -1112,7 +1112,7 @@ static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
return -ENODEV;
}
- CPP_DBG("open %d %p\n", i, &fh->vfh);
+ CPP_DBG("open %d %pK\n", i, &fh->vfh);
cpp_dev->cpp_open_cnt++;
if (cpp_dev->cpp_open_cnt == 1) {
rc = cpp_init_hardware(cpp_dev);
@@ -1158,7 +1158,7 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
cpp_dev = v4l2_get_subdevdata(sd);
if (!cpp_dev) {
- pr_err("failed: cpp_dev %p\n", cpp_dev);
+ pr_err("failed: cpp_dev %pK\n", cpp_dev);
return -EINVAL;
}
@@ -1446,7 +1446,7 @@ static void msm_cpp_do_timeout_work(struct work_struct *work)
mutex_lock(&cpp_dev->mutex);
if (!work || (cpp_timer.data.cpp_dev->state != CPP_STATE_ACTIVE)) {
- pr_err("Invalid work:%p or state:%d\n", work,
+ pr_err("Invalid work:%pK or state:%d\n", work,
cpp_timer.data.cpp_dev->state);
/* Do not flush queue here as it is not a fatal error */
goto end;
@@ -2512,7 +2512,7 @@ static int msm_cpp_copy_from_ioctl_ptr(void *dst_ptr,
{
int ret;
if ((ioctl_ptr->ioctl_ptr == NULL) || (ioctl_ptr->len == 0)) {
- pr_err("%s: Wrong ioctl_ptr %p / len %zu\n", __func__,
+ pr_err("%s: Wrong ioctl_ptr %pK / len %zu\n", __func__,
ioctl_ptr, ioctl_ptr->len);
return -EINVAL;
}
@@ -2535,7 +2535,7 @@ static int msm_cpp_copy_from_ioctl_ptr(void *dst_ptr,
{
int ret;
if ((ioctl_ptr->ioctl_ptr == NULL) || (ioctl_ptr->len == 0)) {
- pr_err("%s: Wrong ioctl_ptr %p / len %zu\n", __func__,
+ pr_err("%s: Wrong ioctl_ptr %pK / len %zu\n", __func__,
ioctl_ptr, ioctl_ptr->len);
return -EINVAL;
}
@@ -2607,14 +2607,14 @@ static int msm_cpp_validate_input(unsigned int cmd, void *arg,
break;
default: {
if (ioctl_ptr == NULL) {
- pr_err("Wrong ioctl_ptr %p\n", ioctl_ptr);
+ pr_err("Wrong ioctl_ptr %pK\n", ioctl_ptr);
return -EINVAL;
}
*ioctl_ptr = arg;
if ((*ioctl_ptr == NULL) ||
((*ioctl_ptr)->ioctl_ptr == NULL)) {
- pr_err("Wrong arg %p\n", arg);
+ pr_err("Wrong arg %pK\n", arg);
return -EINVAL;
}
break;
@@ -2631,7 +2631,7 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
int rc = 0;
if (sd == NULL) {
- pr_err("sd %p\n", sd);
+ pr_err("sd %pK\n", sd);
return -EINVAL;
}
cpp_dev = v4l2_get_subdevdata(sd);
@@ -2707,7 +2707,7 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
&cpp_dev->pdev->dev);
if (rc) {
dev_err(&cpp_dev->pdev->dev,
- "Fail to loc blob %s dev %p, rc:%d\n",
+ "Fail to loc blob %s dev %pK, rc:%d\n",
cpp_dev->fw_name_bin,
&cpp_dev->pdev->dev, rc);
kfree(cpp_dev->fw_name_bin);
@@ -3170,14 +3170,15 @@ static long msm_cpp_subdev_do_ioctl(
struct v4l2_fh *vfh = NULL;
if ((arg == NULL) || (file == NULL)) {
- pr_err("Invalid input parameters arg %p, file %p\n", arg, file);
+ pr_err("Invalid input parameters arg %pK, file %pK\n",
+ arg, file);
return -EINVAL;
}
vdev = video_devdata(file);
sd = vdev_to_v4l2_subdev(vdev);
if (sd == NULL) {
- pr_err("Invalid input parameter sd %p\n", sd);
+ pr_err("Invalid input parameter sd %pK\n", sd);
return -EINVAL;
}
vfh = file->private_data;
@@ -3451,7 +3452,7 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
}
cpp_dev = v4l2_get_subdevdata(sd);
if (!vdev || !cpp_dev) {
- pr_err("Invalid vdev %p or cpp_dev %p structures!",
+ pr_err("Invalid vdev %pK or cpp_dev %pK structures!",
vdev, cpp_dev);
return -EINVAL;
}
diff --git a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
index bf4d3595ecf4..f2f1dca81f18 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
@@ -56,12 +56,12 @@ static void vpe_mem_dump(const char * const name, const void * const addr,
int i;
u32 *p = (u32 *) addr;
u32 data;
- VPE_DBG("%s: (%s) %p %d\n", __func__, name, addr, size);
+ VPE_DBG("%s: (%s) %pK %d\n", __func__, name, addr, size);
line_str[0] = '\0';
p_str = line_str;
for (i = 0; i < size/4; i++) {
if (i % 4 == 0) {
- snprintf(p_str, 12, "%p: ", p);
+ snprintf(p_str, 12, "%pK: ", p);
p_str += 10;
}
data = *p++;
@@ -614,7 +614,7 @@ static int vpe_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
goto err_mutex_unlock;
}
- VPE_DBG("open %d %p\n", i, &fh->vfh);
+ VPE_DBG("open %d %pK\n", i, &fh->vfh);
vpe_dev->vpe_open_cnt++;
if (vpe_dev->vpe_open_cnt == 1) {
rc = vpe_init_hardware(vpe_dev);
@@ -669,7 +669,7 @@ static int vpe_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
return -ENODEV;
}
- VPE_DBG("close %d %p\n", i, &fh->vfh);
+ VPE_DBG("close %d %pK\n", i, &fh->vfh);
vpe_dev->vpe_open_cnt--;
if (vpe_dev->vpe_open_cnt == 0) {
vpe_deinit_mem(vpe_dev);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index 0ad3d9a51f20..c33e66fdbbb5 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -583,7 +583,7 @@ static int32_t msm_actuator_move_focus(
if ((a_ctrl->region_size <= 0) ||
(a_ctrl->region_size > MAX_ACTUATOR_REGION) ||
(!move_params->ringing_params)) {
- pr_err("Invalid-region size = %d, ringing_params = %p\n",
+ pr_err("Invalid-region size = %d, ringing_params = %pK\n",
a_ctrl->region_size, move_params->ringing_params);
return -EFAULT;
}
@@ -703,7 +703,7 @@ static int32_t msm_actuator_bivcm_move_focus(
if ((a_ctrl->region_size <= 0) ||
(a_ctrl->region_size > MAX_ACTUATOR_REGION) ||
(!move_params->ringing_params)) {
- pr_err("Invalid-region size = %d, ringing_params = %p\n",
+ pr_err("Invalid-region size = %d, ringing_params = %pK\n",
a_ctrl->region_size, move_params->ringing_params);
return -EFAULT;
}
@@ -1516,7 +1516,7 @@ static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
struct msm_actuator_ctrl_t *a_ctrl = v4l2_get_subdevdata(sd);
void __user *argp = (void __user *)arg;
CDBG("Enter\n");
- CDBG("%s:%d a_ctrl %p argp %p\n", __func__, __LINE__, a_ctrl, argp);
+ CDBG("%s:%d a_ctrl %pK argp %pK\n", __func__, __LINE__, a_ctrl, argp);
switch (cmd) {
case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
return msm_actuator_get_subdev_id(a_ctrl, argp);
@@ -1777,7 +1777,7 @@ static int32_t msm_actuator_i2c_probe(struct i2c_client *client,
goto probe_failure;
}
- CDBG("client = 0x%p\n", client);
+ CDBG("client = 0x%pK\n", client);
rc = of_property_read_u32(client->dev.of_node, "cell-index",
&act_ctrl_t->subdev_id);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index 7099d9f7d7ae..817870e7d814 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -945,7 +945,7 @@ static int32_t msm_cci_i2c_read_bytes(struct v4l2_subdev *sd,
uint16_t read_bytes = 0;
if (!sd || !c_ctrl) {
- pr_err("%s:%d sd %p c_ctrl %p\n", __func__,
+ pr_err("%s:%d sd %pK c_ctrl %pK\n", __func__,
__LINE__, sd, c_ctrl);
return -EINVAL;
}
@@ -1238,7 +1238,7 @@ static int32_t msm_cci_i2c_set_sync_prms(struct v4l2_subdev *sd,
cci_dev = v4l2_get_subdevdata(sd);
if (!cci_dev || !c_ctrl) {
- pr_err("%s:%d failed: invalid params %p %p\n", __func__,
+ pr_err("%s:%d failed: invalid params %pK %pK\n", __func__,
__LINE__, cci_dev, c_ctrl);
rc = -EINVAL;
return rc;
@@ -1260,7 +1260,7 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd,
cci_dev = v4l2_get_subdevdata(sd);
if (!cci_dev || !c_ctrl) {
- pr_err("%s:%d failed: invalid params %p %p\n", __func__,
+ pr_err("%s:%d failed: invalid params %pK %pK\n", __func__,
__LINE__, cci_dev, c_ctrl);
rc = -EINVAL;
return rc;
@@ -1539,7 +1539,7 @@ static int32_t msm_cci_write(struct v4l2_subdev *sd,
cci_dev = v4l2_get_subdevdata(sd);
if (!cci_dev || !c_ctrl) {
- pr_err("%s:%d failed: invalid params %p %p\n", __func__,
+ pr_err("%s:%d failed: invalid params %pK %pK\n", __func__,
__LINE__, cci_dev, c_ctrl);
rc = -EINVAL;
return rc;
@@ -1984,7 +1984,7 @@ static int msm_cci_probe(struct platform_device *pdev)
{
struct cci_device *new_cci_dev;
int rc = 0, i = 0;
- CDBG("%s: pdev %p device id = %d\n", __func__, pdev, pdev->id);
+ CDBG("%s: pdev %pK device id = %d\n", __func__, pdev, pdev->id);
new_cci_dev = kzalloc(sizeof(struct cci_device), GFP_KERNEL);
if (!new_cci_dev) {
pr_err("%s: no enough memory\n", __func__);
@@ -1996,7 +1996,7 @@ static int msm_cci_probe(struct platform_device *pdev)
ARRAY_SIZE(new_cci_dev->msm_sd.sd.name), "msm_cci");
v4l2_set_subdevdata(&new_cci_dev->msm_sd.sd, new_cci_dev);
platform_set_drvdata(pdev, &new_cci_dev->msm_sd.sd);
- CDBG("%s sd %p\n", __func__, &new_cci_dev->msm_sd.sd);
+ CDBG("%s sd %pK\n", __func__, &new_cci_dev->msm_sd.sd);
if (pdev->dev.of_node)
of_property_read_u32((&pdev->dev)->of_node,
"cell-index", &pdev->id);
@@ -2071,7 +2071,7 @@ static int msm_cci_probe(struct platform_device *pdev)
if (!new_cci_dev->write_wq[i])
pr_err("Failed to create write wq\n");
}
- CDBG("%s cci subdev %p\n", __func__, &new_cci_dev->msm_sd.sd);
+ CDBG("%s cci subdev %pK\n", __func__, &new_cci_dev->msm_sd.sd);
CDBG("%s line %d\n", __func__, __LINE__);
return 0;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
index ef07a540bbe2..46e859464acb 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
@@ -265,7 +265,7 @@ static int msm_csid_config(struct csid_device *csid_dev,
void __iomem *csidbase;
csidbase = csid_dev->base;
if (!csidbase || !csid_params) {
- pr_err("%s:%d csidbase %p, csid params %p\n", __func__,
+ pr_err("%s:%d csidbase %pK, csid params %pK\n", __func__,
__LINE__, csidbase, csid_params);
return -EINVAL;
}
@@ -651,7 +651,7 @@ static int32_t msm_csid_cmd(struct csid_device *csid_dev, void __user *arg)
struct csid_cfg_data *cdata = (struct csid_cfg_data *)arg;
if (!csid_dev || !cdata) {
- pr_err("%s:%d csid_dev %p, cdata %p\n", __func__, __LINE__,
+ pr_err("%s:%d csid_dev %pK, cdata %pK\n", __func__, __LINE__,
csid_dev, cdata);
return -EINVAL;
}
@@ -792,7 +792,7 @@ static int32_t msm_csid_cmd32(struct csid_device *csid_dev, void __user *arg)
cdata = &local_arg;
if (!csid_dev || !cdata) {
- pr_err("%s:%d csid_dev %p, cdata %p\n", __func__, __LINE__,
+ pr_err("%s:%d csid_dev %pK, cdata %pK\n", __func__, __LINE__,
csid_dev, cdata);
return -EINVAL;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
index cc8eed39701d..7bdaf67ccb25 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
@@ -46,7 +46,7 @@
#define CSI_3PHASE_HW 1
#define MAX_LANES 4
#define CLOCK_OFFSET 0x700
-#define CSIPHY_SOF_DEBUG_COUNT 3
+#define CSIPHY_SOF_DEBUG_COUNT 2
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
@@ -497,7 +497,7 @@ static int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev,
val |= csiphy_params->csid_core;
}
msm_camera_io_w(val, csiphy_dev->clk_mux_base);
- CDBG("%s clk mux addr %p val 0x%x\n", __func__,
+ CDBG("%s clk mux addr %pK val 0x%x\n", __func__,
csiphy_dev->clk_mux_base, val);
/* ensure write is done */
mb();
@@ -623,6 +623,47 @@ static int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev,
return rc;
}
+void msm_csiphy_disable_irq(
+ struct csiphy_device *csiphy_dev)
+{
+ void __iomem *csiphybase;
+
+ csiphybase = csiphy_dev->base;
+ msm_camera_io_w(0,
+ csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl11.addr);
+ msm_camera_io_w(0,
+ csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl12.addr);
+ msm_camera_io_w(0,
+ csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl13.addr);
+ msm_camera_io_w(0,
+ csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl14.addr);
+ msm_camera_io_w(0,
+ csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl15.addr);
+ msm_camera_io_w(0,
+ csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl16.addr);
+ msm_camera_io_w(0,
+ csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl17.addr);
+ msm_camera_io_w(0,
+ csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl18.addr);
+ msm_camera_io_w(0,
+ csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl19.addr);
+ msm_camera_io_w(0,
+ csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl20.addr);
+ msm_camera_io_w(0,
+ csiphybase + csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl21.addr);
+}
+
static irqreturn_t msm_csiphy_irq(int irq_num, void *data)
{
uint32_t irq;
@@ -632,8 +673,10 @@ static irqreturn_t msm_csiphy_irq(int irq_num, void *data)
if (csiphy_dev->csiphy_sof_debug == SOF_DEBUG_ENABLE) {
if (csiphy_dev->csiphy_sof_debug_count < CSIPHY_SOF_DEBUG_COUNT)
csiphy_dev->csiphy_sof_debug_count++;
- else
+ else {
+ msm_csiphy_disable_irq(csiphy_dev);
return IRQ_HANDLED;
+ }
}
for (i = 0; i < csiphy_dev->num_irq_registers; i++) {
@@ -881,7 +924,7 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
mipi_csiphy_glbl_pwr_cfg_addr);
} else {
if (!csi_lane_params) {
- pr_err("%s:%d failed: csi_lane_params %p\n", __func__,
+ pr_err("%s:%d failed: csi_lane_params %pK\n", __func__,
__LINE__, csi_lane_params);
return -EINVAL;
}
@@ -987,7 +1030,7 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
mipi_csiphy_glbl_pwr_cfg_addr);
} else {
if (!csi_lane_params) {
- pr_err("%s:%d failed: csi_lane_params %p\n", __func__,
+ pr_err("%s:%d failed: csi_lane_params %pK\n", __func__,
__LINE__, csi_lane_params);
return -EINVAL;
}
@@ -1027,7 +1070,6 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
mipi_csiphy_glbl_pwr_cfg_addr);
}
if (csiphy_dev->csiphy_sof_debug == SOF_DEBUG_ENABLE) {
- csiphy_dev->csiphy_sof_debug = SOF_DEBUG_DISABLE;
rc = msm_camera_enable_irq(csiphy_dev->irq, false);
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
index 8e5064637f73..c9f2c8c63df8 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
@@ -696,7 +696,7 @@ static long msm_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
struct msm_eeprom_ctrl_t *e_ctrl = v4l2_get_subdevdata(sd);
void __user *argp = (void __user *)arg;
CDBG("%s E\n", __func__);
- CDBG("%s:%d a_ctrl %p argp %p\n", __func__, __LINE__, e_ctrl, argp);
+ CDBG("%s:%d a_ctrl %pK argp %pK\n", __func__, __LINE__, e_ctrl, argp);
switch (cmd) {
case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
return msm_eeprom_get_subdev_id(e_ctrl, argp);
@@ -795,7 +795,7 @@ static int msm_eeprom_i2c_probe(struct i2c_client *client,
}
e_ctrl->eeprom_v4l2_subdev_ops = &msm_eeprom_subdev_ops;
e_ctrl->eeprom_mutex = &msm_eeprom_mutex;
- CDBG("%s client = 0x%p\n", __func__, client);
+ CDBG("%s client = 0x%pK\n", __func__, client);
e_ctrl->eboard_info = (struct msm_eeprom_board_info *)(id->driver_data);
if (!e_ctrl->eboard_info) {
pr_err("%s:%d board info NULL\n", __func__, __LINE__);
@@ -1521,7 +1521,7 @@ static long msm_eeprom_subdev_ioctl32(struct v4l2_subdev *sd,
void __user *argp = (void __user *)arg;
CDBG("%s E\n", __func__);
- CDBG("%s:%d a_ctrl %p argp %p\n", __func__, __LINE__, e_ctrl, argp);
+ CDBG("%s:%d a_ctrl %pK argp %pK\n", __func__, __LINE__, e_ctrl, argp);
switch (cmd) {
case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
return msm_eeprom_get_subdev_id(e_ctrl, argp);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
index 86d61e7a8185..84bd3fe3fb85 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
@@ -347,7 +347,7 @@ static int32_t msm_flash_i2c_release(
int32_t rc = 0;
if (!(&flash_ctrl->power_info) || !(&flash_ctrl->flash_i2c_client)) {
- pr_err("%s:%d failed: %p %p\n",
+ pr_err("%s:%d failed: %pK %pK\n",
__func__, __LINE__, &flash_ctrl->power_info,
&flash_ctrl->flash_i2c_client);
return -EINVAL;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
index af4723520045..6b867bfb5c4a 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
@@ -34,7 +34,7 @@ int msm_camera_fill_vreg_params(struct camera_vreg_t *cam_vreg,
/* Validate input parameters */
if (!cam_vreg || !power_setting) {
- pr_err("%s:%d failed: cam_vreg %p power_setting %p", __func__,
+ pr_err("%s:%d failed: cam_vreg %pK power_setting %pK", __func__,
__LINE__, cam_vreg, power_setting);
return -EINVAL;
}
@@ -1327,7 +1327,7 @@ int msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl,
CDBG("%s:%d\n", __func__, __LINE__);
if (!ctrl || !sensor_i2c_client) {
- pr_err("failed ctrl %p sensor_i2c_client %p\n", ctrl,
+ pr_err("failed ctrl %pK sensor_i2c_client %pK\n", ctrl,
sensor_i2c_client);
return -EINVAL;
}
@@ -1549,7 +1549,7 @@ int msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl,
CDBG("%s:%d\n", __func__, __LINE__);
if (!ctrl || !sensor_i2c_client) {
- pr_err("failed ctrl %p sensor_i2c_client %p\n", ctrl,
+ pr_err("failed ctrl %pK sensor_i2c_client %pK\n", ctrl,
sensor_i2c_client);
return -EINVAL;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
index 6a4dcdce43d6..d09e29dd4af0 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
@@ -106,7 +106,7 @@ int msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
struct msm_camera_i2c_client *sensor_i2c_client;
if (!s_ctrl) {
- pr_err("%s:%d failed: s_ctrl %p\n",
+ pr_err("%s:%d failed: s_ctrl %pK\n",
__func__, __LINE__, s_ctrl);
return -EINVAL;
}
@@ -119,7 +119,7 @@ int msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
sensor_i2c_client = s_ctrl->sensor_i2c_client;
if (!power_info || !sensor_i2c_client) {
- pr_err("%s:%d failed: power_info %p sensor_i2c_client %p\n",
+ pr_err("%s:%d failed: power_info %pK sensor_i2c_client %pK\n",
__func__, __LINE__, power_info, sensor_i2c_client);
return -EINVAL;
}
@@ -137,7 +137,7 @@ int msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
uint32_t retry = 0;
if (!s_ctrl) {
- pr_err("%s:%d failed: %p\n",
+ pr_err("%s:%d failed: %pK\n",
__func__, __LINE__, s_ctrl);
return -EINVAL;
}
@@ -152,7 +152,7 @@ int msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
if (!power_info || !sensor_i2c_client || !slave_info ||
!sensor_name) {
- pr_err("%s:%d failed: %p %p %p %p\n",
+ pr_err("%s:%d failed: %pK %pK %pK %pK\n",
__func__, __LINE__, power_info,
sensor_i2c_client, slave_info, sensor_name);
return -EINVAL;
@@ -208,7 +208,7 @@ int msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl)
const char *sensor_name;
if (!s_ctrl) {
- pr_err("%s:%d failed: %p\n",
+ pr_err("%s:%d failed: %pK\n",
__func__, __LINE__, s_ctrl);
return -EINVAL;
}
@@ -217,7 +217,7 @@ int msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl)
sensor_name = s_ctrl->sensordata->sensor_name;
if (!sensor_i2c_client || !slave_info || !sensor_name) {
- pr_err("%s:%d failed: %p %p %p\n",
+ pr_err("%s:%d failed: %pK %pK %pK\n",
__func__, __LINE__, sensor_i2c_client, slave_info,
sensor_name);
return -EINVAL;
@@ -1450,13 +1450,13 @@ int32_t msm_sensor_init_default_params(struct msm_sensor_ctrl_t *s_ctrl)
/* Validate input parameters */
if (!s_ctrl) {
- pr_err("%s:%d failed: invalid params s_ctrl %p\n", __func__,
+ pr_err("%s:%d failed: invalid params s_ctrl %pK\n", __func__,
__LINE__, s_ctrl);
return -EINVAL;
}
if (!s_ctrl->sensor_i2c_client) {
- pr_err("%s:%d failed: invalid params sensor_i2c_client %p\n",
+ pr_err("%s:%d failed: invalid params sensor_i2c_client %pK\n",
__func__, __LINE__, s_ctrl->sensor_i2c_client);
return -EINVAL;
}
@@ -1465,7 +1465,7 @@ int32_t msm_sensor_init_default_params(struct msm_sensor_ctrl_t *s_ctrl)
s_ctrl->sensor_i2c_client->cci_client = kzalloc(sizeof(
struct msm_camera_cci_client), GFP_KERNEL);
if (!s_ctrl->sensor_i2c_client->cci_client) {
- pr_err("%s:%d failed: no memory cci_client %p\n", __func__,
+ pr_err("%s:%d failed: no memory cci_client %pK\n", __func__,
__LINE__, s_ctrl->sensor_i2c_client->cci_client);
return -ENOMEM;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
index 36ad8470a916..d075a6d25b3e 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
@@ -474,10 +474,8 @@ static int32_t msm_sensor_get_power_down_settings(void *setting,
}
/* Allocate memory for power down setting */
pd = kzalloc(sizeof(*pd) * size_down, GFP_KERNEL);
- if (!pd) {
- pr_err("failed: no memory power_setting %p", pd);
+ if (!pd)
return -EFAULT;
- }
if (slave_info->power_setting_array.power_down_setting) {
#ifdef CONFIG_COMPAT
@@ -541,10 +539,8 @@ static int32_t msm_sensor_get_power_up_settings(void *setting,
/* Allocate memory for power up setting */
pu = kzalloc(sizeof(*pu) * size, GFP_KERNEL);
- if (!pu) {
- pr_err("failed: no memory power_setting %p", pu);
+ if (!pu)
return -ENOMEM;
- }
#ifdef CONFIG_COMPAT
if (is_compat_task()) {
@@ -655,22 +651,20 @@ int32_t msm_sensor_driver_probe(void *setting,
/* Validate input parameters */
if (!setting) {
- pr_err("failed: slave_info %p", setting);
+ pr_err("failed: slave_info %pK", setting);
return -EINVAL;
}
/* Allocate memory for slave info */
slave_info = kzalloc(sizeof(*slave_info), GFP_KERNEL);
- if (!slave_info) {
- pr_err("failed: no memory slave_info %p", slave_info);
+ if (!slave_info)
return -ENOMEM;
- }
#ifdef CONFIG_COMPAT
if (is_compat_task()) {
struct msm_camera_sensor_slave_info32 *slave_info32 =
kzalloc(sizeof(*slave_info32), GFP_KERNEL);
if (!slave_info32) {
- pr_err("failed: no memory for slave_info32 %p\n",
+ pr_err("failed: no memory for slave_info32 %pK\n",
slave_info32);
rc = -ENOMEM;
goto free_slave_info;
@@ -765,13 +759,13 @@ int32_t msm_sensor_driver_probe(void *setting,
/* Extract s_ctrl from camera id */
s_ctrl = g_sctrl[slave_info->camera_id];
if (!s_ctrl) {
- pr_err("failed: s_ctrl %p for camera_id %d", s_ctrl,
+ pr_err("failed: s_ctrl %pK for camera_id %d", s_ctrl,
slave_info->camera_id);
rc = -EINVAL;
goto free_slave_info;
}
- CDBG("s_ctrl[%d] %p", slave_info->camera_id, s_ctrl);
+ CDBG("s_ctrl[%d] %pK", slave_info->camera_id, s_ctrl);
if (s_ctrl->is_probe_succeed == 1) {
/*
@@ -811,12 +805,9 @@ int32_t msm_sensor_driver_probe(void *setting,
camera_info = kzalloc(sizeof(struct msm_camera_slave_info), GFP_KERNEL);
- if (!camera_info) {
- pr_err("failed: no memory slave_info %p", camera_info);
+ if (!camera_info)
goto free_slave_info;
- }
-
s_ctrl->sensordata->slave_info = camera_info;
/* Fill sensor slave info */
@@ -828,7 +819,7 @@ int32_t msm_sensor_driver_probe(void *setting,
/* Fill CCI master, slave address and CCI default params */
if (!s_ctrl->sensor_i2c_client) {
- pr_err("failed: sensor_i2c_client %p",
+ pr_err("failed: sensor_i2c_client %pK",
s_ctrl->sensor_i2c_client);
rc = -EINVAL;
goto free_camera_info;
@@ -841,7 +832,7 @@ int32_t msm_sensor_driver_probe(void *setting,
cci_client = s_ctrl->sensor_i2c_client->cci_client;
if (!cci_client) {
- pr_err("failed: cci_client %p", cci_client);
+ pr_err("failed: cci_client %pK", cci_client);
goto free_camera_info;
}
cci_client->cci_i2c_master = s_ctrl->cci_i2c_master;
@@ -1129,7 +1120,7 @@ static int32_t msm_sensor_driver_parse(struct msm_sensor_ctrl_t *s_ctrl)
s_ctrl->sensor_i2c_client = kzalloc(sizeof(*s_ctrl->sensor_i2c_client),
GFP_KERNEL);
if (!s_ctrl->sensor_i2c_client) {
- pr_err("failed: no memory sensor_i2c_client %p",
+ pr_err("failed: no memory sensor_i2c_client %pK",
s_ctrl->sensor_i2c_client);
return -ENOMEM;
}
@@ -1138,7 +1129,7 @@ static int32_t msm_sensor_driver_parse(struct msm_sensor_ctrl_t *s_ctrl)
s_ctrl->msm_sensor_mutex = kzalloc(sizeof(*s_ctrl->msm_sensor_mutex),
GFP_KERNEL);
if (!s_ctrl->msm_sensor_mutex) {
- pr_err("failed: no memory msm_sensor_mutex %p",
+ pr_err("failed: no memory msm_sensor_mutex %pK",
s_ctrl->msm_sensor_mutex);
goto FREE_SENSOR_I2C_CLIENT;
}
@@ -1167,7 +1158,7 @@ static int32_t msm_sensor_driver_parse(struct msm_sensor_ctrl_t *s_ctrl)
/* Store sensor control structure in static database */
g_sctrl[s_ctrl->id] = s_ctrl;
- CDBG("g_sctrl[%d] %p", s_ctrl->id, g_sctrl[s_ctrl->id]);
+ CDBG("g_sctrl[%d] %pK", s_ctrl->id, g_sctrl[s_ctrl->id]);
return rc;
@@ -1191,10 +1182,8 @@ static int32_t msm_sensor_driver_platform_probe(struct platform_device *pdev)
/* Create sensor control structure */
s_ctrl = kzalloc(sizeof(*s_ctrl), GFP_KERNEL);
- if (!s_ctrl) {
- pr_err("failed: no memory s_ctrl %p", s_ctrl);
+ if (!s_ctrl)
return -ENOMEM;
- }
platform_set_drvdata(pdev, s_ctrl);
@@ -1238,10 +1227,8 @@ static int32_t msm_sensor_driver_i2c_probe(struct i2c_client *client,
/* Create sensor control structure */
s_ctrl = kzalloc(sizeof(*s_ctrl), GFP_KERNEL);
- if (!s_ctrl) {
- pr_err("failed: no memory s_ctrl %p", s_ctrl);
+ if (!s_ctrl)
return -ENOMEM;
- }
i2c_set_clientdata(client, s_ctrl);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c
index 8b6e3d3e1f78..ed0b9742bddb 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, 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
@@ -64,7 +64,7 @@ static int32_t msm_sensor_driver_cmd(struct msm_sensor_init_t *s_init,
/* Validate input parameters */
if (!s_init || !cfg) {
- pr_err("failed: s_init %p cfg %p", s_init, cfg);
+ pr_err("failed: s_init %pK cfg %pK", s_init, cfg);
return -EINVAL;
}
@@ -106,7 +106,7 @@ static long msm_sensor_init_subdev_ioctl(struct v4l2_subdev *sd,
/* Validate input parameters */
if (!s_init) {
- pr_err("failed: s_init %p", s_init);
+ pr_err("failed: s_init %pK", s_init);
return -EINVAL;
}
@@ -167,12 +167,10 @@ static int __init msm_sensor_init_module(void)
int ret = 0;
/* Allocate memory for msm_sensor_init control structure */
s_init = kzalloc(sizeof(struct msm_sensor_init_t), GFP_KERNEL);
- if (!s_init) {
- pr_err("failed: no memory s_init %p", NULL);
+ if (!s_init)
return -ENOMEM;
- }
- CDBG("MSM_SENSOR_INIT_MODULE %p", NULL);
+ CDBG("MSM_SENSOR_INIT_MODULE %pK", NULL);
/* Initialize mutex */
mutex_init(&s_init->imutex);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
index 947eeafc480c..82c9e5c5befa 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
@@ -448,7 +448,7 @@ static long msm_ois_subdev_ioctl(struct v4l2_subdev *sd,
struct msm_ois_ctrl_t *o_ctrl = v4l2_get_subdevdata(sd);
void __user *argp = (void __user *)arg;
CDBG("Enter\n");
- CDBG("%s:%d o_ctrl %p argp %p\n", __func__, __LINE__, o_ctrl, argp);
+ CDBG("%s:%d o_ctrl %pK argp %pK\n", __func__, __LINE__, o_ctrl, argp);
switch (cmd) {
case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
return msm_ois_get_subdev_id(o_ctrl, argp);
@@ -553,7 +553,7 @@ static int32_t msm_ois_i2c_probe(struct i2c_client *client,
goto probe_failure;
}
- CDBG("client = 0x%p\n", client);
+ CDBG("client = 0x%pK\n", client);
rc = of_property_read_u32(client->dev.of_node, "cell-index",
&ois_ctrl_t->subdev_id);
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index db0ea848a964..dd9973b965f9 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -108,6 +108,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
struct hfi_frame_size *frame_sz;
struct hfi_profile_level *profile_level;
struct hfi_bit_depth *pixel_depth;
+ struct hfi_pic_struct *pic_struct;
u8 *data_ptr;
int prop_id;
enum msm_vidc_pixel_depth luma_bit_depth, chroma_bit_depth;
@@ -193,6 +194,17 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
chroma_bit_depth);
data_ptr += sizeof(struct hfi_bit_depth);
break;
+ case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
+ data_ptr = data_ptr + sizeof(u32);
+ pic_struct = (struct hfi_pic_struct *) data_ptr;
+ event_notify.pic_struct =
+ pic_struct->progressive_only;
+ dprintk(VIDC_DBG,
+ "Progressive only flag: %d\n",
+ pic_struct->progressive_only);
+ data_ptr +=
+ sizeof(struct hfi_pic_struct);
+ break;
default:
dprintk(VIDC_ERR,
"%s cmd: %#x not supported\n",
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 6f58437368f3..2ad0a7349de8 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -3015,17 +3015,8 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
atomic_inc(&inst->seq_hdr_reqs);
break;
case V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME:
- if (ctrl->val < inst->capability.ltr_count.min ||
- ctrl->val >= inst->capability.ltr_count.max) {
- dprintk(VIDC_ERR,
- "Error setting useltr %d range: [%d,%d)\n",
- ctrl->val, inst->capability.ltr_count.min,
- inst->capability.ltr_count.max);
- rc = -ENOTSUPP;
- break;
- }
property_id = HAL_CONFIG_VENC_USELTRFRAME;
- use_ltr.ref_ltr = (0x1 << ctrl->val);
+ use_ltr.ref_ltr = ctrl->val;
use_ltr.use_constraint = false;
use_ltr.frames = 0;
pdata = &use_ltr;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 4ed5bff2d0a7..f03693096311 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -1176,6 +1176,7 @@ void *msm_vidc_open(int core_id, int session_type)
inst->core = core;
inst->bit_depth = MSM_VIDC_BIT_DEPTH_8;
inst->instant_bitrate = 0;
+ inst->pic_struct = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index e889a6046eca..120f651ecf0f 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -44,8 +44,6 @@
V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT
#define V4L2_EVENT_RELEASE_BUFFER_REFERENCE \
V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE
-#define V4L2_EVENT_SEQ_BITDEPTH_CHANGED_INSUFFICIENT \
- V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT
#define MAX_SUPPORTED_INSTANCES 16
@@ -1023,8 +1021,8 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
int event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
struct v4l2_event seq_changed_event = {0};
int rc = 0;
- bool bit_depth_changed = false;
struct hfi_device *hdev;
+ u32 *ptr = NULL;
if (!event_notify) {
dprintk(VIDC_WARN, "Got an empty event from hfi\n");
@@ -1144,23 +1142,46 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
break;
}
+ /* Bit depth and pic struct changed event are combined into a single
+ * event (insufficient event) for the userspace. Currently bitdepth
+ * changes is only for HEVC and interlaced support is for all
+ * codecs except HEVC
+ * event data is now as follows:
+ * u32 *ptr = seq_changed_event.u.data;
+ * ptr[0] = height
+ * ptr[1] = width
+ * ptr[2] = flag to indicate bit depth or/and pic struct changed
+ * ptr[3] = bit depth
+ * ptr[4] = pic struct (progressive or interlaced)
+ */
+
+ ptr = (u32 *)seq_changed_event.u.data;
+ ptr[2] = 0x0;
+ ptr[3] = inst->bit_depth;
+ ptr[4] = inst->pic_struct;
+
+ if (inst->bit_depth != event_notify->bit_depth) {
+ inst->bit_depth = event_notify->bit_depth;
+ ptr[2] |= V4L2_EVENT_BITDEPTH_FLAG;
+ ptr[3] = inst->bit_depth;
+ event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
+ dprintk(VIDC_DBG,
+ "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to bit-depth change\n");
+ }
+
+ if (inst->pic_struct != event_notify->pic_struct) {
+ inst->pic_struct = event_notify->pic_struct;
+ event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
+ ptr[2] |= V4L2_EVENT_PICSTRUCT_FLAG;
+ ptr[4] = inst->pic_struct;
+ dprintk(VIDC_DBG,
+ "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to pic-struct change\n");
+ }
+
if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) {
dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n");
inst->reconfig_height = event_notify->height;
inst->reconfig_width = event_notify->width;
-
- if (inst->bit_depth != event_notify->bit_depth) {
- inst->bit_depth = event_notify->bit_depth;
- bit_depth_changed = true;
- seq_changed_event.u.data[0] = inst->bit_depth;
- event = V4L2_EVENT_SEQ_BITDEPTH_CHANGED_INSUFFICIENT;
- dprintk(VIDC_DBG,
- "V4L2_EVENT_SEQ_BITDEPTH_CHANGED_INSUFFICIENT\n");
- } else {
- dprintk(VIDC_DBG,
- "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n");
- }
-
inst->in_reconfig = true;
} else {
dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_SUFFICIENT\n");
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 113c6ccb326b..19459647abbe 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -290,6 +290,7 @@ struct msm_vidc_inst {
unsigned long instant_bitrate;
u32 buffers_held_in_driver;
atomic_t in_flush;
+ u32 pic_struct;
};
extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 5118fb43699f..64a4d9717901 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -3278,6 +3278,26 @@ exit:
return;
}
+static void __dump_venus_debug_registers(struct venus_hfi_device *device)
+{
+ u32 reg;
+
+ dprintk(VIDC_ERR, "Dumping Venus registers...\n");
+ reg = __read_register(device, VENUS_VBIF_XIN_HALT_CTRL1);
+ dprintk(VIDC_ERR, "VENUS_VBIF_XIN_HALT_CTRL1: 0x%x\n", reg);
+
+ reg = __read_register(device,
+ VIDC_VENUS_WRAPPER_MMCC_VENUS0_POWER_STATUS);
+ dprintk(VIDC_ERR,
+ "VIDC_VENUS_WRAPPER_MMCC_VENUS0_POWER_STATUS: 0x%x\n", reg);
+
+ reg = __read_register(device, VIDC_WRAPPER_CPU_STATUS);
+ dprintk(VIDC_ERR, "VIDC_WRAPPER_CPU_STATUS: 0x%x\n", reg);
+
+ reg = __read_register(device, VIDC_CPU_CS_SCIACMDARG0);
+ dprintk(VIDC_ERR, "VIDC_CPU_CS_SCIACMDARG0: 0x%x\n", reg);
+}
+
static void __process_sys_error(struct venus_hfi_device *device)
{
struct hfi_sfr_struct *vsfr = NULL;
@@ -3393,6 +3413,7 @@ static int __response_handler(struct venus_hfi_device *device)
dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
vsfr->rg_data);
+ __dump_venus_debug_registers(device);
dprintk(VIDC_ERR, "Received watchdog timeout\n");
packets[packet_count++] = info;
goto exit;
@@ -3417,6 +3438,7 @@ static int __response_handler(struct venus_hfi_device *device)
/* Process the packet types that we're interested in */
switch (info->response_type) {
case HAL_SYS_ERROR:
+ __dump_venus_debug_registers(device);
__process_sys_error(device);
break;
case HAL_SYS_RELEASE_RESOURCE_DONE:
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index dcaf9ce8d1bb..063208b8f188 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -1338,6 +1338,7 @@ struct msm_vidc_cb_event {
u32 hal_event_type;
ion_phys_addr_t packet_buffer;
ion_phys_addr_t extra_data_buffer;
+ u32 pic_struct;
};
struct msm_vidc_cb_data_done {
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 04f006c50f27..ad438d9d03af 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -291,6 +291,9 @@ struct hfi_buffer_info {
(HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x003)
#define HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH \
(HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x007)
+#define HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT \
+ (HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x009)
+
#define HFI_PROPERTY_CONFIG_VDEC_COMMON_START \
(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_COMMON_OFFSET + 0x4000)
@@ -419,6 +422,10 @@ struct hfi_buffer_info {
#define HFI_PROPERTY_CONFIG_VPE_OPERATIONS \
(HFI_PROPERTY_CONFIG_VPE_COMMON_START + 0x002)
+struct hfi_pic_struct {
+ u32 progressive_only;
+};
+
struct hfi_bitrate {
u32 bit_rate;
u32 layer_id;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_io.h b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
index ae84cfff2a38..35a68de3a1a2 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_io.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -139,6 +139,7 @@
#define VIDC_VBIF_AT_OLD_HIGH (VIDC_VBIF_BASE_OFFS + 0xC08)
#define VIDC_VBIF_AT_NEW_BASE (VIDC_VBIF_BASE_OFFS + 0xC10)
#define VIDC_VBIF_AT_NEW_HIGH (VIDC_VBIF_BASE_OFFS + 0xC18)
+#define VENUS_VBIF_XIN_HALT_CTRL1 (VIDC_VBIF_BASE_OFFS + 0x204)
#define VENUS_VBIF_AXI_HALT_CTRL0 (VIDC_VBIF_BASE_OFFS + 0x208)
#define VENUS_VBIF_AXI_HALT_CTRL1 (VIDC_VBIF_BASE_OFFS + 0x20C)
@@ -150,6 +151,8 @@
(VIDC_WRAPPER_BASE_OFFS + 0x20)
#define VIDC_VENUS0_WRAPPER_VBIF_PRIORITY_LEVEL \
(VIDC_WRAPPER_BASE_OFFS + 0x24)
+#define VIDC_VENUS_WRAPPER_MMCC_VENUS0_POWER_STATUS \
+ (VIDC_WRAPPER_BASE_OFFS + 0x44)
#define VIDC_CTRL_INIT 0x000D2048
#define VIDC_CTRL_INIT_RESERVED_BITS31_1__M 0xFFFFFFFE
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 2c3b6674a161..786cf5f55ffe 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -432,7 +432,6 @@ static int qseecom_scm_call2(uint32_t svc_id, uint32_t tz_cmd_id,
smc_id = TZ_OS_APP_SHUTDOWN_ID;
desc.arginfo = TZ_OS_APP_SHUTDOWN_ID_PARAM_ID;
desc.args[0] = req->app_id;
- __qseecom_reentrancy_check_if_no_app_blocked(smc_id);
ret = scm_call2(smc_id, &desc);
break;
}
@@ -2218,6 +2217,9 @@ static int qseecom_unload_app(struct qseecom_dev_handle *data,
return 0;
}
+ __qseecom_cleanup_app(data);
+ __qseecom_reentrancy_check_if_no_app_blocked(TZ_OS_APP_SHUTDOWN_ID);
+
if (data->client.app_id > 0) {
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
list_for_each_entry(ptr_app, &qseecom.registered_app_list_head,
@@ -2246,11 +2248,9 @@ static int qseecom_unload_app(struct qseecom_dev_handle *data,
}
}
- if (found_dead_app) {
+ if (found_dead_app)
pr_warn("cleanup app_id %d(%s)\n", data->client.app_id,
(char *)data->client.app_name);
- __qseecom_cleanup_app(data);
- }
if (unload) {
struct qseecom_unload_app_ireq req;
@@ -2279,7 +2279,6 @@ static int qseecom_unload_app(struct qseecom_dev_handle *data,
if (resp.result == QSEOS_RESULT_SUCCESS)
pr_debug("App (%d) is unloaded!!\n",
data->client.app_id);
- __qseecom_cleanup_app(data);
if (resp.result == QSEOS_RESULT_INCOMPLETE) {
ret = __qseecom_process_incomplete_cmd(data, &resp);
if (ret) {
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index ad857aa1d1fe..bfa6fe51445d 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -2389,9 +2389,16 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
goto out;
if (mmc_can_sleepawake(host)) {
+ /*
+ * For caching host->ios to cached_ios we need to
+ * make sure that clocks are not gated otherwise
+ * cached_ios->clock will be 0.
+ */
+ mmc_host_clk_hold(host);
memcpy(&host->cached_ios, &host->ios, sizeof(host->cached_ios));
mmc_cache_card_ext_csd(host);
err = mmc_sleepawake(host, true);
+ mmc_host_clk_release(host);
} else if (!mmc_host_is_spi(host)) {
err = mmc_deselect_cards(host);
}
diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index c1aaf0336cf2..3702e2823cc1 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -712,13 +712,26 @@ struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi,
int err = 0;
struct ubi_ainf_peb *aeb, *tmp_aeb;
- if (!list_empty(&ai->free)) {
- aeb = list_entry(ai->free.next, struct ubi_ainf_peb, u.list);
+ list_for_each_entry_safe(aeb, tmp_aeb, &ai->free, u.list) {
list_del(&aeb->u.list);
+ if (aeb->ec == UBI_UNKNOWN) {
+ ubi_err(ubi, "PEB %d in freelist has unknown EC",
+ aeb->pnum);
+ aeb->ec = ai->mean_ec;
+ }
+ err = early_erase_peb(ubi, ai, aeb->pnum, aeb->ec+1);
+ if (err) {
+ ubi_err(ubi, "Erase failed for PEB %d in freelist",
+ aeb->pnum);
+ list_add(&aeb->u.list, &ai->erase);
+ continue;
+ }
+ aeb->ec += 1;
dbg_bld("return free PEB %d, EC %d", aeb->pnum, aeb->ec);
return aeb;
}
+
/*
* We try to erase the first physical eraseblock from the erase list
* and pick it if we succeed, or try to erase the next one if not. And
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 617541e86f80..3575202c9ff3 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -1105,9 +1105,11 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
* Re-erase the PEB before using it. This should minimize any issues
* from decay of charge in this block.
*/
- err = ubi_wl_erase_peb(ubi, pnum);
- if (err)
- return err;
+ if (ubi->wl_is_inited) {
+ err = ubi_wl_erase_peb(ubi, pnum);
+ if (err)
+ return err;
+ }
err = self_check_peb_ec_hdr(ubi, pnum);
if (err)
@@ -1128,8 +1130,10 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
p = (char *)vid_hdr - ubi->vid_hdr_shift;
err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset,
ubi->vid_hdr_alsize);
- if (!err)
+
+ if (!err && ubi->wl_is_inited)
ubi_wl_update_peb_sqnum(ubi, pnum, vid_hdr);
+
return err;
}
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index fdb1931f66ed..cb0389933c45 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -598,6 +598,7 @@ struct ubi_device {
char bgt_name[sizeof(UBI_BGT_NAME_PATTERN)+2];
bool scrub_in_progress;
atomic_t scrub_work_count;
+ int wl_is_inited;
/* I/O sub-system's stuff */
long long flash_size;
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 22a30bbaa1bd..e3dfaa4d7eee 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1873,6 +1873,7 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
if (err)
goto out_free;
+ ubi->wl_is_inited = 1;
return 0;
out_free:
diff --git a/drivers/net/wireless/cnss/Kconfig b/drivers/net/wireless/cnss/Kconfig
index 0e46da4e646e..3291f4ad6179 100644
--- a/drivers/net/wireless/cnss/Kconfig
+++ b/drivers/net/wireless/cnss/Kconfig
@@ -9,29 +9,6 @@ config CNSS
This driver also adds support to integrate WLAN module to subsystem
restart framework.
-config CNSS_PCI
- tristate "Flag to enable platform driver for PCIe based wifi device"
- select CNSS
- depends on PCI
- depends on PCI_MSI
- ---help---
- This module specifies whether CNSS Platform Driver supports PCI.
- This flag needs to be disabled if CNSS platform Driver need to be
- supported for other buses.
- The Flag depends on the CNSS Platform Driver and PCI. This Flag
- is used by the CLD driver to use the PCIe exported API's through
- CNSS Driver.
-
-config CNSS_SDIO
- tristate "Flag to enable platform driver for SIDO based wifi device"
- select CNSS
- depends on MMC_SDHCI
- depends on MMC_SDHCI_MSM
- ---help---
- This module specifies whether CNSS Platform Driver supports SDIO.
- This flag needs to be disabled if CNSS platform Driver need to be
- supported for other buses.
-
config CNSS_MAC_BUG
bool "Enable/disable 0-4K memory initialization for QCA6174"
depends on CNSS
diff --git a/drivers/net/wireless/cnss/Makefile b/drivers/net/wireless/cnss/Makefile
index 8f6f88524d4a..ed450da8cbfb 100644
--- a/drivers/net/wireless/cnss/Makefile
+++ b/drivers/net/wireless/cnss/Makefile
@@ -1,6 +1,6 @@
# Makefile for CNSS platform driver
-obj-$(CONFIG_CNSS_PCI) += cnss_pci.o
-obj-$(CONFIG_CNSS_SDIO) += cnss_sdio.o
+obj-$(CONFIG_CNSS) += cnss_pci.o
+obj-$(CONFIG_CNSS) += cnss_sdio.o
obj-$(CONFIG_CNSS) += cnss_common.o
obj-$(CONFIG_HTC_WLAN_NV) += custom_platdev.o
diff --git a/drivers/net/wireless/cnss/cnss_common.c b/drivers/net/wireless/cnss/cnss_common.c
index 428c2f6ad5e6..3709604a2df6 100644
--- a/drivers/net/wireless/cnss/cnss_common.c
+++ b/drivers/net/wireless/cnss/cnss_common.c
@@ -244,7 +244,7 @@ EXPORT_SYMBOL(cnss_dump_stack);
enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
{
- if (!dev && !dev->bus)
+ if (!dev || !dev->bus)
return CNSS_BUS_NONE;
if (memcmp(dev->bus->name, "sdio", 4) == 0)
@@ -255,122 +255,127 @@ enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
return CNSS_BUS_NONE;
}
-#ifdef CONFIG_CNSS_SDIO
int cnss_common_request_bus_bandwidth(struct device *dev, int bandwidth)
{
- if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
- return cnss_sdio_request_bus_bandwidth(bandwidth);
- else
- return 0;
-}
-EXPORT_SYMBOL(cnss_common_request_bus_bandwidth);
-
-void *cnss_common_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
-{
- if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
- return cnss_sdio_get_virt_ramdump_mem(size);
- else
- return NULL;
-}
-EXPORT_SYMBOL(cnss_common_get_virt_ramdump_mem);
-
-void cnss_common_device_self_recovery(struct device *dev)
-{
- if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
- cnss_sdio_device_self_recovery();
-}
-EXPORT_SYMBOL(cnss_common_device_self_recovery);
-
-void cnss_common_schedule_recovery_work(struct device *dev)
-{
- if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
- cnss_sdio_schedule_recovery_work();
-}
-EXPORT_SYMBOL(cnss_common_schedule_recovery_work);
-
-void cnss_common_device_crashed(struct device *dev)
-{
- if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
- cnss_sdio_device_crashed();
-}
-EXPORT_SYMBOL(cnss_common_device_crashed);
-
-u8 *cnss_common_get_wlan_mac_address(struct device *dev, uint32_t *num)
-{
- if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
- return cnss_sdio_get_wlan_mac_address(num);
- else
- return NULL;
-}
-EXPORT_SYMBOL(cnss_common_get_wlan_mac_address);
-
-int cnss_common_set_wlan_mac_address(
- struct device *dev, const u8 *in, uint32_t len)
-{
- if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
- return cnss_sdio_set_wlan_mac_address(in, len);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL(cnss_common_set_wlan_mac_address);
-#endif
+ int ret;
+
+ switch (cnss_get_dev_bus_type(dev)) {
+ case CNSS_BUS_SDIO:
+ ret = cnss_sdio_request_bus_bandwidth(bandwidth);
+ break;
+ case CNSS_BUS_PCI:
+ ret = cnss_pci_request_bus_bandwidth(bandwidth);
+ break;
+ default:
+ pr_debug("%s: Invalid device type\n", __func__);
+ ret = -EINVAL;
+ break;
+ }
-#ifdef CONFIG_CNSS_PCI
-int cnss_common_request_bus_bandwidth(struct device *dev, int bandwidth)
-{
- if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
- return cnss_pci_request_bus_bandwidth(bandwidth);
- else
- return 0;
+ return ret;
}
EXPORT_SYMBOL(cnss_common_request_bus_bandwidth);
void *cnss_common_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
{
- if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
+ switch (cnss_get_dev_bus_type(dev)) {
+ case CNSS_BUS_SDIO:
+ return cnss_sdio_get_virt_ramdump_mem(size);
+ case CNSS_BUS_PCI:
return cnss_pci_get_virt_ramdump_mem(size);
- else
+ default:
+ pr_debug("%s: Invalid device type\n", __func__);
return NULL;
+ }
}
EXPORT_SYMBOL(cnss_common_get_virt_ramdump_mem);
void cnss_common_device_self_recovery(struct device *dev)
{
- if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
+ switch (cnss_get_dev_bus_type(dev)) {
+ case CNSS_BUS_SDIO:
+ cnss_sdio_device_self_recovery();
+ break;
+ case CNSS_BUS_PCI:
cnss_pci_device_self_recovery();
+ break;
+ default:
+ pr_debug("%s: Invalid device type\n", __func__);
+ break;
+ }
}
EXPORT_SYMBOL(cnss_common_device_self_recovery);
void cnss_common_schedule_recovery_work(struct device *dev)
{
- if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
+ switch (cnss_get_dev_bus_type(dev)) {
+ case CNSS_BUS_SDIO:
+ cnss_sdio_schedule_recovery_work();
+ break;
+ case CNSS_BUS_PCI:
cnss_pci_schedule_recovery_work();
+ break;
+ default:
+ pr_debug("%s: Invalid device type\n", __func__);
+ break;
+ }
}
EXPORT_SYMBOL(cnss_common_schedule_recovery_work);
void cnss_common_device_crashed(struct device *dev)
{
- if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
+ switch (cnss_get_dev_bus_type(dev)) {
+ case CNSS_BUS_SDIO:
+ cnss_sdio_device_crashed();
+ break;
+ case CNSS_BUS_PCI:
cnss_pci_device_crashed();
+ break;
+ default:
+ pr_debug("%s: Invalid device type\n", __func__);
+ break;
+ }
}
EXPORT_SYMBOL(cnss_common_device_crashed);
u8 *cnss_common_get_wlan_mac_address(struct device *dev, uint32_t *num)
{
- if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
- return cnss_pci_get_wlan_mac_address(num);
- else
- return NULL;
+ u8 *ret;
+
+ switch (cnss_get_dev_bus_type(dev)) {
+ case CNSS_BUS_SDIO:
+ ret = cnss_sdio_get_wlan_mac_address(num);
+ break;
+ case CNSS_BUS_PCI:
+ ret = cnss_pci_get_wlan_mac_address(num);
+ break;
+ default:
+ pr_debug("%s: Invalid device type\n", __func__);
+ ret = NULL;
+ break;
+ }
+ return ret;
}
EXPORT_SYMBOL(cnss_common_get_wlan_mac_address);
int cnss_common_set_wlan_mac_address(
struct device *dev, const u8 *in, uint32_t len)
{
- if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
- return cnss_pcie_set_wlan_mac_address(in, len);
- else
- return -EINVAL;
+ int ret;
+
+ switch (cnss_get_dev_bus_type(dev)) {
+ case CNSS_BUS_SDIO:
+ ret = cnss_sdio_set_wlan_mac_address(in, len);
+ break;
+ case CNSS_BUS_PCI:
+ ret = cnss_pcie_set_wlan_mac_address(in, len);
+ break;
+ default:
+ pr_debug("%s: Invalid device type\n", __func__);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
}
EXPORT_SYMBOL(cnss_common_set_wlan_mac_address);
-#endif
diff --git a/drivers/net/wireless/cnss/cnss_pci.c b/drivers/net/wireless/cnss/cnss_pci.c
index 68aa612e9c4c..a9f553fe6b52 100644
--- a/drivers/net/wireless/cnss/cnss_pci.c
+++ b/drivers/net/wireless/cnss/cnss_pci.c
@@ -41,11 +41,7 @@
#include <linux/scatterlist.h>
#include <linux/log2.h>
#include <linux/etherdevice.h>
-#ifdef CONFIG_PCI_MSM
#include <linux/msm_pcie.h>
-#else
-#include <mach/msm_pcie.h>
-#endif
#include <soc/qcom/subsystem_restart.h>
#include <soc/qcom/subsystem_notif.h>
#include <soc/qcom/ramdump.h>
@@ -1518,6 +1514,95 @@ static void cnss_smmu_remove(struct device *dev)
penv->smmu_mapping = NULL;
}
+#ifdef CONFIG_PCI_MSM
+struct pci_saved_state *cnss_pci_store_saved_state(struct pci_dev *dev)
+{
+ return pci_store_saved_state(dev);
+}
+
+int cnss_msm_pcie_pm_control(
+ enum msm_pcie_pm_opt pm_opt, u32 bus_num,
+ struct pci_dev *pdev, u32 options)
+{
+ return msm_pcie_pm_control(pm_opt, bus_num, pdev, NULL, options);
+}
+
+int cnss_pci_load_and_free_saved_state(
+ struct pci_dev *dev, struct pci_saved_state **state)
+{
+ return pci_load_and_free_saved_state(dev, state);
+}
+
+int cnss_msm_pcie_shadow_control(struct pci_dev *dev, bool enable)
+{
+ return msm_pcie_shadow_control(dev, enable);
+}
+
+int cnss_msm_pcie_deregister_event(struct msm_pcie_register_event *reg)
+{
+ return msm_pcie_deregister_event(reg);
+}
+
+int cnss_msm_pcie_recover_config(struct pci_dev *dev)
+{
+ return msm_pcie_recover_config(dev);
+}
+
+int cnss_msm_pcie_register_event(struct msm_pcie_register_event *reg)
+{
+ return msm_pcie_register_event(reg);
+}
+
+int cnss_msm_pcie_enumerate(u32 rc_idx)
+{
+ return msm_pcie_enumerate(rc_idx);
+}
+#else /* !defined CONFIG_PCI_MSM */
+
+struct pci_saved_state *cnss_pci_store_saved_state(struct pci_dev *dev)
+{
+ return NULL;
+}
+
+int cnss_msm_pcie_pm_control(
+ enum msm_pcie_pm_opt pm_opt, u32 bus_num,
+ struct pci_dev *pdev, u32 options)
+{
+ return -ENODEV;
+}
+
+int cnss_pci_load_and_free_saved_state(
+ struct pci_dev *dev, struct pci_saved_state **state)
+{
+ return 0;
+}
+
+int cnss_msm_pcie_shadow_control(struct pci_dev *dev, bool enable)
+{
+ return -ENODEV;
+}
+
+int cnss_msm_pcie_deregister_event(struct msm_pcie_register_event *reg)
+{
+ return -ENODEV;
+}
+
+int cnss_msm_pcie_recover_config(struct pci_dev *dev)
+{
+ return -ENODEV;
+}
+
+int cnss_msm_pcie_register_event(struct msm_pcie_register_event *reg)
+{
+ return -ENODEV;
+}
+
+int cnss_msm_pcie_enumerate(u32 rc_idx)
+{
+ return -EPROBE_DEFER;
+}
+#endif
+
static int cnss_wlan_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@@ -1570,11 +1655,11 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev,
if (penv->pcie_link_state) {
pci_save_state(pdev);
- penv->saved_state = pci_store_saved_state(pdev);
+ penv->saved_state = cnss_pci_store_saved_state(pdev);
- ret = msm_pcie_pm_control(MSM_PCIE_SUSPEND,
- cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS);
+ ret = cnss_msm_pcie_pm_control(
+ MSM_PCIE_SUSPEND, cnss_get_pci_dev_bus_number(pdev),
+ pdev, PM_OPTIONS);
if (ret) {
pr_err("Failed to shutdown PCIe link\n");
goto err_pcie_suspend;
@@ -1674,7 +1759,7 @@ static int cnss_wlan_pci_suspend(struct device *dev)
if (penv->pcie_link_state) {
pci_save_state(pdev);
- penv->saved_state = pci_store_saved_state(pdev);
+ penv->saved_state = cnss_pci_store_saved_state(pdev);
}
}
penv->monitor_wake_intr = false;
@@ -1698,8 +1783,8 @@ static int cnss_wlan_pci_resume(struct device *dev)
if (wdriver->resume && !penv->pcie_link_down_ind) {
if (penv->saved_state)
- pci_load_and_free_saved_state(pdev,
- &penv->saved_state);
+ cnss_pci_load_and_free_saved_state(
+ pdev, &penv->saved_state);
pci_restore_state(pdev);
ret = wdriver->resume(pdev);
@@ -1867,11 +1952,11 @@ void cnss_pci_recovery_work_handler(struct work_struct *recovery)
cnss_pci_device_self_recovery();
}
-DECLARE_WORK(recovery_work, cnss_pci_recovery_work_handler);
+DECLARE_WORK(cnss_pci_recovery_work, cnss_pci_recovery_work_handler);
void cnss_schedule_recovery_work(void)
{
- schedule_work(&recovery_work);
+ schedule_work(&cnss_pci_recovery_work);
}
EXPORT_SYMBOL(cnss_schedule_recovery_work);
@@ -1898,7 +1983,7 @@ void cnss_pci_events_cb(struct msm_pcie_notify *notify)
spin_unlock_irqrestore(&pci_link_down_lock, flags);
pr_err("PCI link down, schedule recovery\n");
- schedule_work(&recovery_work);
+ schedule_work(&cnss_pci_recovery_work);
break;
case MSM_PCIE_EVENT_WAKEUP:
@@ -1932,13 +2017,13 @@ void cnss_wlan_pci_link_down(void)
spin_unlock_irqrestore(&pci_link_down_lock, flags);
pr_err("PCI link down detected by host driver, schedule recovery!\n");
- schedule_work(&recovery_work);
+ schedule_work(&cnss_pci_recovery_work);
}
EXPORT_SYMBOL(cnss_wlan_pci_link_down);
int cnss_pcie_shadow_control(struct pci_dev *dev, bool enable)
{
- return msm_pcie_shadow_control(dev, enable);
+ return cnss_msm_pcie_shadow_control(dev, enable);
}
EXPORT_SYMBOL(cnss_pcie_shadow_control);
@@ -2224,14 +2309,14 @@ again:
penv->event_reg.mode = MSM_PCIE_TRIGGER_CALLBACK;
penv->event_reg.callback = cnss_pci_events_cb;
penv->event_reg.options = MSM_PCIE_CONFIG_NO_RECOVERY;
- ret = msm_pcie_register_event(&penv->event_reg);
+ ret = cnss_msm_pcie_register_event(&penv->event_reg);
if (ret)
pr_err("%s: PCIe event register failed! %d\n", __func__, ret);
if (!penv->pcie_link_state && !penv->pcie_link_down_ind) {
- ret = msm_pcie_pm_control(MSM_PCIE_RESUME,
- cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS);
+ ret = cnss_msm_pcie_pm_control(
+ MSM_PCIE_RESUME, cnss_get_pci_dev_bus_number(pdev),
+ pdev, PM_OPTIONS);
if (ret) {
pr_err("PCIe link bring-up failed\n");
goto err_pcie_link_up;
@@ -2239,9 +2324,9 @@ again:
penv->pcie_link_state = PCIE_LINK_UP;
} else if (!penv->pcie_link_state && penv->pcie_link_down_ind) {
- ret = msm_pcie_pm_control(MSM_PCIE_RESUME,
- cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS_RESUME_LINK_DOWN);
+ ret = cnss_msm_pcie_pm_control(
+ MSM_PCIE_RESUME, cnss_get_pci_dev_bus_number(pdev),
+ pdev, PM_OPTIONS_RESUME_LINK_DOWN);
if (ret) {
pr_err("PCIe link bring-up failed (link down option)\n");
@@ -2249,7 +2334,7 @@ again:
}
penv->pcie_link_state = PCIE_LINK_UP;
- ret = msm_pcie_recover_config(pdev);
+ ret = cnss_msm_pcie_recover_config(pdev);
if (ret) {
pr_err("cnss: PCI link failed to recover\n");
goto err_pcie_link_up;
@@ -2262,7 +2347,8 @@ again:
if (wdrv->probe) {
if (penv->saved_state)
- pci_load_and_free_saved_state(pdev, &penv->saved_state);
+ cnss_pci_load_and_free_saved_state(
+ pdev, &penv->saved_state);
pci_restore_state(pdev);
@@ -2276,11 +2362,12 @@ again:
goto err_wlan_probe;
}
pci_save_state(pdev);
- penv->saved_state = pci_store_saved_state(pdev);
- msm_pcie_deregister_event(&penv->event_reg);
- msm_pcie_pm_control(MSM_PCIE_SUSPEND,
- cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS);
+ penv->saved_state = cnss_pci_store_saved_state(pdev);
+ cnss_msm_pcie_deregister_event(&penv->event_reg);
+ cnss_msm_pcie_pm_control(
+ MSM_PCIE_SUSPEND,
+ cnss_get_pci_dev_bus_number(pdev),
+ pdev, PM_OPTIONS);
penv->pcie_link_state = PCIE_LINK_DOWN;
cnss_wlan_gpio_set(gpio_info, WLAN_EN_LOW);
msleep(WLAN_ENABLE_DELAY);
@@ -2298,14 +2385,14 @@ again:
err_wlan_probe:
pci_save_state(pdev);
- penv->saved_state = pci_store_saved_state(pdev);
+ penv->saved_state = cnss_pci_store_saved_state(pdev);
err_pcie_link_up:
- msm_pcie_deregister_event(&penv->event_reg);
+ cnss_msm_pcie_deregister_event(&penv->event_reg);
if (penv->pcie_link_state) {
- msm_pcie_pm_control(MSM_PCIE_SUSPEND,
- cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS);
+ cnss_msm_pcie_pm_control(
+ MSM_PCIE_SUSPEND, cnss_get_pci_dev_bus_number(pdev),
+ pdev, PM_OPTIONS);
penv->pcie_link_state = PCIE_LINK_DOWN;
}
@@ -2361,24 +2448,24 @@ void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver)
wcnss_prealloc_check_memory_leak();
wcnss_pre_alloc_reset();
- msm_pcie_deregister_event(&penv->event_reg);
+ cnss_msm_pcie_deregister_event(&penv->event_reg);
if (penv->pcie_link_state && !penv->pcie_link_down_ind) {
pci_save_state(pdev);
- penv->saved_state = pci_store_saved_state(pdev);
+ penv->saved_state = cnss_pci_store_saved_state(pdev);
- if (msm_pcie_pm_control(MSM_PCIE_SUSPEND,
- cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS)) {
+ if (cnss_msm_pcie_pm_control(
+ MSM_PCIE_SUSPEND, cnss_get_pci_dev_bus_number(pdev),
+ pdev, PM_OPTIONS)) {
pr_err("Failed to shutdown PCIe link\n");
return;
}
} else if (penv->pcie_link_state && penv->pcie_link_down_ind) {
penv->saved_state = NULL;
- if (msm_pcie_pm_control(MSM_PCIE_SUSPEND,
- cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS_SUSPEND_LINK_DOWN)) {
+ if (cnss_msm_pcie_pm_control(
+ MSM_PCIE_SUSPEND, cnss_get_pci_dev_bus_number(pdev),
+ pdev, PM_OPTIONS_SUSPEND_LINK_DOWN)) {
pr_err("Failed to shutdown PCIe link (with linkdown option)\n");
return;
}
@@ -2404,10 +2491,10 @@ int cnss_wlan_pm_control(bool vote)
if (!penv || !penv->pdev)
return -ENODEV;
- return msm_pcie_pm_control(
+ return cnss_msm_pcie_pm_control(
vote ? MSM_PCIE_DISABLE_PC : MSM_PCIE_ENABLE_PC,
cnss_get_pci_dev_bus_number(penv->pdev),
- penv->pdev, NULL, PM_OPTIONS);
+ penv->pdev, PM_OPTIONS);
}
EXPORT_SYMBOL(cnss_wlan_pm_control);
#endif
@@ -2426,7 +2513,7 @@ EXPORT_SYMBOL(cnss_release_pm_sem);
void cnss_pci_schedule_recovery_work(void)
{
- schedule_work(&recovery_work);
+ schedule_work(&cnss_pci_recovery_work);
}
void *cnss_pci_get_virt_ramdump_mem(unsigned long *size)
@@ -2493,9 +2580,9 @@ static int cnss_shutdown(const struct subsys_desc *subsys, bool force_stop)
wdrv->shutdown(pdev);
if (penv->pcie_link_state) {
- if (msm_pcie_pm_control(MSM_PCIE_SUSPEND,
- cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS_SUSPEND_LINK_DOWN)) {
+ if (cnss_msm_pcie_pm_control(
+ MSM_PCIE_SUSPEND, cnss_get_pci_dev_bus_number(pdev),
+ pdev, PM_OPTIONS_SUSPEND_LINK_DOWN)) {
pr_debug("cnss: Failed to shutdown PCIe link!\n");
ret = -EFAULT;
}
@@ -2547,16 +2634,17 @@ static int cnss_powerup(const struct subsys_desc *subsys)
}
if (!penv->pcie_link_state) {
- ret = msm_pcie_pm_control(MSM_PCIE_RESUME,
+ ret = cnss_msm_pcie_pm_control(
+ MSM_PCIE_RESUME,
cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS_RESUME_LINK_DOWN);
+ pdev, PM_OPTIONS_RESUME_LINK_DOWN);
if (ret) {
pr_err("cnss: Failed to bring-up PCIe link!\n");
goto err_pcie_link_up;
}
penv->pcie_link_state = PCIE_LINK_UP;
- ret = msm_pcie_recover_config(penv->pdev);
+ ret = cnss_msm_pcie_recover_config(penv->pdev);
if (ret) {
pr_err("cnss: PCI link failed to recover\n");
goto err_pcie_link_up;
@@ -2566,8 +2654,8 @@ static int cnss_powerup(const struct subsys_desc *subsys)
if (wdrv && wdrv->reinit) {
if (penv->saved_state)
- pci_load_and_free_saved_state(pdev,
- &penv->saved_state);
+ cnss_pci_load_and_free_saved_state(
+ pdev, &penv->saved_state);
pci_restore_state(pdev);
@@ -2590,10 +2678,11 @@ out:
err_wlan_reinit:
pci_save_state(pdev);
- penv->saved_state = pci_store_saved_state(pdev);
- msm_pcie_pm_control(MSM_PCIE_SUSPEND,
+ penv->saved_state = cnss_pci_store_saved_state(pdev);
+ cnss_msm_pcie_pm_control(
+ MSM_PCIE_SUSPEND,
cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS);
+ pdev, PM_OPTIONS);
penv->pcie_link_state = PCIE_LINK_DOWN;
err_pcie_link_up:
@@ -2778,7 +2867,7 @@ static int cnss_probe(struct platform_device *pdev)
goto err_get_rc;
}
- ret = msm_pcie_enumerate(rc_num);
+ ret = cnss_msm_pcie_enumerate(rc_num);
if (ret) {
pr_err("%s: Failed to enable PCIe RC%x!\n", __func__, rc_num);
goto err_pcie_enumerate;
@@ -3260,14 +3349,15 @@ int cnss_auto_suspend(void)
if (penv->pcie_link_state) {
pci_save_state(pdev);
- penv->saved_state = pci_store_saved_state(pdev);
+ penv->saved_state = cnss_pci_store_saved_state(pdev);
pci_disable_device(pdev);
ret = pci_set_power_state(pdev, PCI_D3hot);
if (ret)
pr_err("%s: Set D3Hot failed: %d\n", __func__, ret);
- if (msm_pcie_pm_control(MSM_PCIE_SUSPEND,
- cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS)) {
+ if (cnss_msm_pcie_pm_control(
+ MSM_PCIE_SUSPEND,
+ cnss_get_pci_dev_bus_number(pdev),
+ pdev, PM_OPTIONS)) {
pr_err("%s: Failed to shutdown PCIe link\n", __func__);
ret = -EAGAIN;
goto out;
@@ -3294,9 +3384,9 @@ int cnss_auto_resume(void)
pdev = penv->pdev;
if (!penv->pcie_link_state) {
- if (msm_pcie_pm_control(MSM_PCIE_RESUME,
- cnss_get_pci_dev_bus_number(pdev),
- pdev, NULL, PM_OPTIONS)) {
+ if (cnss_msm_pcie_pm_control(
+ MSM_PCIE_RESUME, cnss_get_pci_dev_bus_number(pdev),
+ pdev, PM_OPTIONS)) {
pr_err("%s: Failed to resume PCIe link\n", __func__);
ret = -EAGAIN;
goto out;
@@ -3308,7 +3398,7 @@ int cnss_auto_resume(void)
}
if (penv->saved_state)
- pci_load_and_free_saved_state(pdev, &penv->saved_state);
+ cnss_pci_load_and_free_saved_state(pdev, &penv->saved_state);
pci_restore_state(pdev);
pci_set_master(pdev);
diff --git a/drivers/net/wireless/cnss/cnss_sdio.c b/drivers/net/wireless/cnss/cnss_sdio.c
index e4596cc67be1..a43dc60ec424 100644
--- a/drivers/net/wireless/cnss/cnss_sdio.c
+++ b/drivers/net/wireless/cnss/cnss_sdio.c
@@ -214,74 +214,6 @@ void cnss_sdio_remove_pm_qos(void)
}
EXPORT_SYMBOL(cnss_sdio_remove_pm_qos);
-int cnss_request_bus_bandwidth(int bandwidth)
-{
- int ret;
- struct cnss_sdio_bus_bandwidth *bus_bandwidth;
-
- if (!cnss_pdata)
- return -ENODEV;
-
- bus_bandwidth = &cnss_pdata->bus_bandwidth;
- if (!bus_bandwidth->bus_client)
- return -ENOSYS;
-
- switch (bandwidth) {
- case CNSS_BUS_WIDTH_NONE:
- case CNSS_BUS_WIDTH_LOW:
- case CNSS_BUS_WIDTH_MEDIUM:
- case CNSS_BUS_WIDTH_HIGH:
- ret = msm_bus_scale_client_update_request(
- bus_bandwidth->bus_client, bandwidth);
- if (!ret) {
- bus_bandwidth->current_bandwidth_vote = bandwidth;
- } else {
- pr_debug(
- "%s: could not set bus bandwidth %d, ret = %d\n",
- __func__, bandwidth, ret);
- }
- break;
- default:
- pr_debug("%s: Invalid request %d", __func__, bandwidth);
- ret = -EINVAL;
- }
-
- return ret;
-}
-EXPORT_SYMBOL(cnss_request_bus_bandwidth);
-
-void cnss_request_pm_qos_type(int latency_type, u32 qos_val)
-{
- if (!cnss_pdata)
- return;
-
- pr_debug("%s: PM QoS value: %d\n", __func__, qos_val);
- pm_qos_add_request(&cnss_pdata->qos_request, latency_type, qos_val);
-}
-EXPORT_SYMBOL(cnss_request_pm_qos_type);
-
-void cnss_request_pm_qos(u32 qos_val)
-{
- if (!cnss_pdata)
- return;
-
- pr_debug("%s: PM QoS value: %d\n", __func__, qos_val);
- pm_qos_add_request(
- &cnss_pdata->qos_request,
- PM_QOS_CPU_DMA_LATENCY, qos_val);
-}
-EXPORT_SYMBOL(cnss_request_pm_qos);
-
-void cnss_remove_pm_qos(void)
-{
- if (!cnss_pdata)
- return;
-
- pm_qos_remove_request(&cnss_pdata->qos_request);
- pr_debug("%s: PM QoS removed\n", __func__);
-}
-EXPORT_SYMBOL(cnss_remove_pm_qos);
-
static int cnss_sdio_shutdown(const struct subsys_desc *subsys, bool force_stop)
{
struct cnss_sdio_info *cnss_info;
@@ -578,56 +510,17 @@ void cnss_sdio_device_crashed(void)
}
}
-void *cnss_get_virt_ramdump_mem(unsigned long *size)
-{
- if (!cnss_pdata || !cnss_pdata->pdev)
- return NULL;
-
- *size = cnss_pdata->ssr_info.ramdump_size;
-
- return cnss_pdata->ssr_info.ramdump_addr;
-}
-EXPORT_SYMBOL(cnss_get_virt_ramdump_mem);
-
-void cnss_device_self_recovery(void)
-{
- cnss_sdio_shutdown(NULL, false);
- msleep(WLAN_RECOVERY_DELAY);
- cnss_sdio_powerup(NULL);
-}
-EXPORT_SYMBOL(cnss_device_self_recovery);
-
static void cnss_sdio_recovery_work_handler(struct work_struct *recovery)
{
cnss_sdio_device_self_recovery();
}
-DECLARE_WORK(recovery_work, cnss_sdio_recovery_work_handler);
+DECLARE_WORK(cnss_sdio_recovery_work, cnss_sdio_recovery_work_handler);
void cnss_sdio_schedule_recovery_work(void)
{
- schedule_work(&recovery_work);
-}
-
-void cnss_schedule_recovery_work(void)
-{
- schedule_work(&recovery_work);
+ schedule_work(&cnss_sdio_recovery_work);
}
-EXPORT_SYMBOL(cnss_schedule_recovery_work);
-
-void cnss_device_crashed(void)
-{
- struct cnss_ssr_info *ssr_info;
-
- if (!cnss_pdata)
- return;
- ssr_info = &cnss_pdata->ssr_info;
- if (ssr_info->subsys) {
- subsys_set_crash_status(ssr_info->subsys, true);
- subsystem_restart_dev(ssr_info->subsys);
- }
-}
-EXPORT_SYMBOL(cnss_device_crashed);
/**
* cnss_get_restart_level() - cnss get restart level API
@@ -1277,13 +1170,6 @@ u8 *cnss_sdio_get_wlan_mac_address(uint32_t *num)
}
EXPORT_SYMBOL(cnss_sdio_get_wlan_mac_address);
-u8 *cnss_get_wlan_mac_address(struct device *dev, uint32_t *num)
-{
- *num = 0;
- return NULL;
-}
-EXPORT_SYMBOL(cnss_get_wlan_mac_address);
-
static const struct of_device_id cnss_sdio_dt_match[] = {
{.compatible = "qcom,cnss_sdio"},
{}
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index 4e3d1411ce89..218af71d6112 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -585,6 +585,8 @@ struct msm_pcie_dev_t {
uint32_t cpl_timeout;
uint32_t current_bdf;
short current_short_bdf;
+ uint32_t perst_delay_us_min;
+ uint32_t perst_delay_us_max;
uint32_t tlp_rd_size;
bool linkdown_panic;
bool ep_wakeirq;
@@ -1822,6 +1824,10 @@ static void msm_pcie_show_status(struct msm_pcie_dev_t *dev)
dev->cpl_timeout);
PCIE_DBG_FS(dev, "current_bdf: 0x%x\n",
dev->current_bdf);
+ PCIE_DBG_FS(dev, "perst_delay_us_min: %dus\n",
+ dev->perst_delay_us_min);
+ PCIE_DBG_FS(dev, "perst_delay_us_max: %dus\n",
+ dev->perst_delay_us_max);
PCIE_DBG_FS(dev, "tlp_rd_size: 0x%x\n",
dev->tlp_rd_size);
PCIE_DBG_FS(dev, "rc_corr_counter: %lu\n",
@@ -4256,8 +4262,7 @@ int msm_pcie_enable(struct msm_pcie_dev_t *dev, u32 options)
dev->rc_idx);
gpio_set_value(dev->gpio[MSM_PCIE_GPIO_PERST].num,
1 - dev->gpio[MSM_PCIE_GPIO_PERST].on);
- usleep_range(PERST_PROPAGATION_DELAY_US_MIN,
- PERST_PROPAGATION_DELAY_US_MAX);
+ usleep_range(dev->perst_delay_us_min, dev->perst_delay_us_max);
/* set max tlp read size */
msm_pcie_write_reg_field(dev->dm_core, PCIE20_DEVICE_CONTROL_STATUS,
@@ -5121,7 +5126,7 @@ static irqreturn_t handle_msi_irq(int irq, void *data)
struct msm_pcie_dev_t *dev = data;
void __iomem *ctrl_status;
- PCIE_DBG(dev, "irq=%d\n", irq);
+ PCIE_DUMP(dev, "irq: %d\n", irq);
/* check for set bits, clear it by setting that bit
and trigger corresponding irq */
@@ -5772,6 +5777,34 @@ static int msm_pcie_probe(struct platform_device *pdev)
PCIE_DBG(&msm_pcie_dev[rc_idx], "RC%d: cpl-timeout: 0x%x.\n",
rc_idx, msm_pcie_dev[rc_idx].cpl_timeout);
+ msm_pcie_dev[rc_idx].perst_delay_us_min =
+ PERST_PROPAGATION_DELAY_US_MIN;
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,perst-delay-us-min",
+ &msm_pcie_dev[rc_idx].perst_delay_us_min);
+ if (ret)
+ PCIE_DBG(&msm_pcie_dev[rc_idx],
+ "RC%d: perst-delay-us-min does not exist. Use default value %dus.\n",
+ rc_idx, msm_pcie_dev[rc_idx].perst_delay_us_min);
+ else
+ PCIE_DBG(&msm_pcie_dev[rc_idx],
+ "RC%d: perst-delay-us-min: %dus.\n",
+ rc_idx, msm_pcie_dev[rc_idx].perst_delay_us_min);
+
+ msm_pcie_dev[rc_idx].perst_delay_us_max =
+ PERST_PROPAGATION_DELAY_US_MAX;
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,perst-delay-us-max",
+ &msm_pcie_dev[rc_idx].perst_delay_us_max);
+ if (ret)
+ PCIE_DBG(&msm_pcie_dev[rc_idx],
+ "RC%d: perst-delay-us-max does not exist. Use default value %dus.\n",
+ rc_idx, msm_pcie_dev[rc_idx].perst_delay_us_max);
+ else
+ PCIE_DBG(&msm_pcie_dev[rc_idx],
+ "RC%d: perst-delay-us-max: %dus.\n",
+ rc_idx, msm_pcie_dev[rc_idx].perst_delay_us_max);
+
msm_pcie_dev[rc_idx].tlp_rd_size = PCIE_TLP_RD_SIZE;
ret = of_property_read_u32(pdev->dev.of_node,
"qcom,tlp-rd-size",
diff --git a/drivers/platform/msm/ipa/ipa_api.c b/drivers/platform/msm/ipa/ipa_api.c
index 13ea3b2fb920..f4a2d17db38d 100644
--- a/drivers/platform/msm/ipa/ipa_api.c
+++ b/drivers/platform/msm/ipa/ipa_api.c
@@ -2503,6 +2503,32 @@ int ipa_set_required_perf_profile(enum ipa_voltage_level floor_voltage,
}
EXPORT_SYMBOL(ipa_set_required_perf_profile);
+/**
+ * ipa_get_ipc_logbuf() - return a pointer to IPA driver IPC log
+ */
+void *ipa_get_ipc_logbuf(void)
+{
+ void *ret;
+
+ IPA_API_DISPATCH_RETURN_PTR(ipa_get_ipc_logbuf);
+
+ return ret;
+}
+EXPORT_SYMBOL(ipa_get_ipc_logbuf);
+
+/**
+ * ipa_get_ipc_logbuf_low() - return a pointer to IPA driver IPC low prio log
+ */
+void *ipa_get_ipc_logbuf_low(void)
+{
+ void *ret;
+
+ IPA_API_DISPATCH_RETURN_PTR(ipa_get_ipc_logbuf_low);
+
+ return ret;
+}
+EXPORT_SYMBOL(ipa_get_ipc_logbuf_low);
+
static const struct dev_pm_ops ipa_pm_ops = {
.suspend_noirq = ipa_ap_suspend,
.resume_noirq = ipa_ap_resume,
diff --git a/drivers/platform/msm/ipa/ipa_api.h b/drivers/platform/msm/ipa/ipa_api.h
index 7edbf4e5b1d9..054b3654e9dc 100644
--- a/drivers/platform/msm/ipa/ipa_api.h
+++ b/drivers/platform/msm/ipa/ipa_api.h
@@ -303,6 +303,10 @@ struct ipa_api_controller {
int (*ipa_set_required_perf_profile)(
enum ipa_voltage_level floor_voltage, u32 bandwidth_mbps);
+ void *(*ipa_get_ipc_logbuf)(void);
+
+ void *(*ipa_get_ipc_logbuf_low)(void);
+
};
#ifdef CONFIG_IPA
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c
index c9abf140d8e3..21a230c3c1ff 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c
@@ -34,52 +34,42 @@
#define IPA_USB_DRV_NAME "ipa_usb"
-#define IPA_USB_IPC_LOG_PAGES 10
-#define IPA_USB_IPC_LOG(buf, fmt, args...) \
- ipc_log_string((buf), \
- DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
#define IPA_USB_DBG(fmt, args...) \
do { \
pr_debug(IPA_USB_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
- if (ipa3_usb_ctx) { \
- IPA_USB_IPC_LOG(ipa3_usb_ctx->logbuf, fmt, ## args); \
- IPA_USB_IPC_LOG(ipa3_usb_ctx->logbuf_low, \
- fmt, ## args); \
- } \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPA_USB_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_USB_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define IPA_USB_DBG_LOW(fmt, args...) \
do { \
pr_debug(IPA_USB_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
- if (ipa3_usb_ctx && \
- ipa3_usb_ctx->enable_low_prio_print) { \
- IPA_USB_IPC_LOG(ipa3_usb_ctx->logbuf_low, \
- fmt, ## args); \
- } \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_USB_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define IPA_USB_ERR(fmt, args...) \
do { \
pr_err(IPA_USB_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
- if (ipa3_usb_ctx) { \
- IPA_USB_IPC_LOG(ipa3_usb_ctx->logbuf, fmt, ## args); \
- IPA_USB_IPC_LOG(ipa3_usb_ctx->logbuf_low, \
- fmt, ## args); \
- } \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPA_USB_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_USB_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define IPA_USB_INFO(fmt, args...) \
do { \
pr_info(IPA_USB_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
- if (ipa3_usb_ctx) { \
- IPA_USB_IPC_LOG(ipa3_usb_ctx->logbuf, fmt, ## args); \
- IPA_USB_IPC_LOG(ipa3_usb_ctx->logbuf_low, \
- fmt, ## args); \
- } \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPA_USB_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_USB_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
struct ipa_usb_xdci_connect_params_internal {
@@ -189,10 +179,6 @@ struct ipa3_usb_context {
ttype_ctx[IPA_USB_TRANSPORT_MAX];
struct dentry *dfile_state_info;
struct dentry *dent;
- struct dentry *dfile_enable_low_prio;
- void *logbuf;
- void *logbuf_low;
- u32 enable_low_prio_print;
};
enum ipa3_usb_op {
@@ -492,7 +478,7 @@ static void ipa3_usb_notify_do(enum ipa3_usb_transport_type ttype,
void *user_data;
int res;
- IPA_USB_DBG_LOW("Trying to notify USB with %s\n",
+ IPA_USB_DBG("Trying to notify USB with %s\n",
ipa3_usb_notify_event_to_string(event));
cb = ipa3_usb_ctx->ttype_ctx[ttype].ipa_usb_notify_cb;
@@ -500,7 +486,7 @@ static void ipa3_usb_notify_do(enum ipa3_usb_transport_type ttype,
if (cb) {
res = cb(event, user_data);
- IPA_USB_DBG_LOW("Notified USB with %s. is_dpl=%d result=%d\n",
+ IPA_USB_DBG("Notified USB with %s. is_dpl=%d result=%d\n",
ipa3_usb_notify_event_to_string(event),
IPA3_USB_IS_TTYPE_DPL(ttype), res);
}
@@ -1229,7 +1215,7 @@ static int ipa3_usb_request_xdci_channel(
chan_params.chan_params.ring_base_addr =
params->xfer_ring_base_addr;
chan_params.chan_params.ring_base_vaddr = NULL;
- chan_params.chan_params.use_db_eng = GSI_CHAN_DIRECT_MODE;
+ chan_params.chan_params.use_db_eng = GSI_CHAN_DB_MODE;
chan_params.chan_params.max_prefetch = GSI_ONE_PREFETCH_SEG;
if (params->dir == GSI_CHAN_DIR_FROM_GSI)
chan_params.chan_params.low_weight =
@@ -1250,6 +1236,9 @@ static int ipa3_usb_request_xdci_channel(
params->xfer_scratch.depcmd_low_addr;
chan_params.chan_scratch.xdci.depcmd_hi_addr =
params->xfer_scratch.depcmd_hi_addr;
+ chan_params.chan_scratch.xdci.outstanding_threshold =
+ ((params->teth_prot == IPA_USB_MBIM) ? 1 : 2) *
+ chan_params.chan_params.re_size;
/* max_outstanding_tre is set in ipa3_request_gsi_channel() */
result = ipa3_request_gsi_channel(&chan_params, out_params);
if (result) {
@@ -1789,33 +1778,6 @@ connect_ul_fail:
return result;
}
-static int ipa_usb_ipc_logging_init(void)
-{
- int result;
-
- ipa3_usb_ctx->logbuf = ipc_log_context_create(IPA_USB_IPC_LOG_PAGES,
- "ipa_usb", 0);
- if (ipa3_usb_ctx->logbuf == NULL) {
- /* we can't use ipa_usb print macros on failures */
- pr_err("ipa_usb: failed to get logbuf\n");
- return -ENOMEM;
- }
-
- ipa3_usb_ctx->logbuf_low = ipc_log_context_create(IPA_USB_IPC_LOG_PAGES,
- "ipa_usb_low", 0);
- if (ipa3_usb_ctx->logbuf_low == NULL) {
- pr_err("ipa_usb: failed to get logbuf_low\n");
- result = -ENOMEM;
- goto fail_logbuf_low;
- }
-
- return 0;
-
-fail_logbuf_low:
- ipc_log_context_destroy(ipa3_usb_ctx->logbuf);
- return result;
-}
-
#ifdef CONFIG_DEBUG_FS
static char dbg_buff[IPA_USB_MAX_MSG_LEN];
@@ -1980,8 +1942,6 @@ const struct file_operations ipa3_ipa_usb_ops = {
static void ipa_usb_debugfs_init(void)
{
const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH;
- const mode_t read_write_mode = S_IRUSR | S_IRGRP | S_IROTH |
- S_IWUSR | S_IWGRP;
ipa3_usb_ctx->dent = debugfs_create_dir("ipa_usb", 0);
if (IS_ERR(ipa3_usb_ctx->dent)) {
@@ -1998,16 +1958,6 @@ static void ipa_usb_debugfs_init(void)
goto fail;
}
- ipa3_usb_ctx->dfile_enable_low_prio =
- debugfs_create_u32("enable_low_prio_print",
- read_write_mode, ipa3_usb_ctx->dent,
- &ipa3_usb_ctx->enable_low_prio_print);
- if (!ipa3_usb_ctx->dfile_enable_low_prio ||
- IS_ERR(ipa3_usb_ctx->dfile_enable_low_prio)) {
- IPA_USB_ERR("could not create enable_low_prio_print file\n");
- goto fail;
- }
-
return;
fail:
@@ -2620,14 +2570,6 @@ static int __init ipa3_usb_init(void)
}
memset(ipa3_usb_ctx, 0, sizeof(struct ipa3_usb_context));
- res = ipa_usb_ipc_logging_init();
- if (res) {
- /* IPA_USB_ERR will crash on NULL dereference if we use macro*/
- pr_err("ipa_usb: failed to initialize ipc logging\n");
- res = -EFAULT;
- goto ipa_usb_init_ipc_log_fail;
- }
-
for (i = 0; i < IPA_USB_MAX_TETH_PROT_SIZE; i++)
ipa3_usb_ctx->teth_prot_ctx[i].state =
IPA_USB_TETH_PROT_INVALID;
@@ -2668,9 +2610,6 @@ static int __init ipa3_usb_init(void)
ipa_usb_workqueue_fail:
IPA_USB_ERR(":init failed (%d)\n", -res);
- ipc_log_context_destroy(ipa3_usb_ctx->logbuf);
- ipc_log_context_destroy(ipa3_usb_ctx->logbuf_low);
-ipa_usb_init_ipc_log_fail:
kfree(ipa3_usb_ctx);
return res;
}
diff --git a/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c b/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c
index c388925f4679..521bdafab76f 100644
--- a/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c
+++ b/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c
@@ -23,49 +23,37 @@
#include <linux/types.h>
#include <linux/ipv6.h>
#include <net/addrconf.h>
-#include <linux/ipc_logging.h>
#include <linux/ipa.h>
#include <linux/cdev.h>
#include <linux/ipa_odu_bridge.h>
+#include "../ipa_common_i.h"
#define ODU_BRIDGE_DRV_NAME "odu_ipa_bridge"
-#define ODU_IPC_LOG_PAGES 10
-#define ODU_IPC_LOG(buf, fmt, args...) \
- ipc_log_string((buf), \
- ODU_BRIDGE_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
-
#define ODU_BRIDGE_DBG(fmt, args...) \
do { \
pr_debug(ODU_BRIDGE_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
- if (odu_bridge_ctx) { \
- ODU_IPC_LOG(odu_bridge_ctx->logbuf, \
- fmt, ## args); \
- ODU_IPC_LOG(odu_bridge_ctx->logbuf_low, \
- fmt, ## args); \
- } \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ ODU_BRIDGE_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ ODU_BRIDGE_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define ODU_BRIDGE_DBG_LOW(fmt, args...) \
do { \
pr_debug(ODU_BRIDGE_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
- if (odu_bridge_ctx && \
- odu_bridge_ctx->enable_low_prio_print) { \
- ODU_IPC_LOG(odu_bridge_ctx->logbuf_low, \
- fmt, ## args); \
- } \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ ODU_BRIDGE_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define ODU_BRIDGE_ERR(fmt, args...) \
do { \
pr_err(ODU_BRIDGE_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
- if (odu_bridge_ctx) { \
- ODU_IPC_LOG(odu_bridge_ctx->logbuf, \
- fmt, ## args); \
- ODU_IPC_LOG(odu_bridge_ctx->logbuf_low, \
- fmt, ## args); \
- } \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ ODU_BRIDGE_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ ODU_BRIDGE_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define ODU_BRIDGE_FUNC_ENTRY() \
@@ -158,7 +146,6 @@ struct odu_bridge_ctx {
u32 ipa_sys_desc_size;
void *logbuf;
void *logbuf_low;
- u32 enable_low_prio_print;
};
static struct odu_bridge_ctx *odu_bridge_ctx;
@@ -683,7 +670,6 @@ static long compat_odu_bridge_ioctl(struct file *file,
static struct dentry *dent;
static struct dentry *dfile_stats;
static struct dentry *dfile_mode;
-static struct dentry *dfile_low_prio;
static ssize_t odu_debugfs_stats(struct file *file,
char __user *ubuf,
@@ -806,15 +792,6 @@ static void odu_debugfs_init(void)
goto fail;
}
- dfile_low_prio = debugfs_create_u32("enable_low_prio_print",
- read_write_mode,
- dent, &odu_bridge_ctx->enable_low_prio_print);
- if (!dfile_low_prio) {
- ODU_BRIDGE_ERR("could not create enable_low_prio_print file\n");
- goto fail;
- }
-
- return;
fail:
debugfs_remove_recursive(dent);
}
@@ -1104,34 +1081,6 @@ static void odu_bridge_deregister_properties(void)
ODU_BRIDGE_FUNC_EXIT();
}
-static int odu_bridge_ipc_logging_init(void)
-{
- int result;
-
- odu_bridge_ctx->logbuf = ipc_log_context_create(ODU_IPC_LOG_PAGES,
- "ipa_odu_bridge", 0);
- if (odu_bridge_ctx->logbuf == NULL) {
- /* we can't use odu_bridge print macros on failures */
- pr_err("odu_bridge: failed to get logbuf\n");
- return -ENOMEM;
- }
-
- odu_bridge_ctx->logbuf_low =
- ipc_log_context_create(ODU_IPC_LOG_PAGES,
- "ipa_odu_bridge_low", 0);
- if (odu_bridge_ctx->logbuf_low == NULL) {
- pr_err("odu_bridge: failed to get logbuf_low\n");
- result = -ENOMEM;
- goto fail_logbuf_low;
- }
-
- return 0;
-
-fail_logbuf_low:
- ipc_log_context_destroy(odu_bridge_ctx->logbuf);
- return result;
-}
-
/**
* odu_bridge_init() - Initialize the ODU bridge driver
* @params: initialization parameters
@@ -1183,13 +1132,6 @@ int odu_bridge_init(struct odu_bridge_params *params)
return -ENOMEM;
}
- res = odu_bridge_ipc_logging_init();
- if (res) {
- /* ODU_BRIDGE_ERR will crash on NULL if we use it here*/
- pr_err("odu_bridge: failed to initialize ipc logging\n");
- res = -EFAULT;
- goto fail_ipc_create;
- }
odu_bridge_ctx->class = class_create(THIS_MODULE, ODU_BRIDGE_DRV_NAME);
if (!odu_bridge_ctx->class) {
ODU_BRIDGE_ERR("Class_create err.\n");
@@ -1264,9 +1206,6 @@ fail_device_create:
fail_alloc_chrdev_region:
class_destroy(odu_bridge_ctx->class);
fail_class_create:
- ipc_log_context_destroy(odu_bridge_ctx->logbuf);
- ipc_log_context_destroy(odu_bridge_ctx->logbuf_low);
-fail_ipc_create:
kfree(odu_bridge_ctx);
odu_bridge_ctx = NULL;
return res;
diff --git a/drivers/platform/msm/ipa/ipa_common_i.h b/drivers/platform/msm/ipa/ipa_common_i.h
index 8149837b2de0..d906169f7098 100644
--- a/drivers/platform/msm/ipa/ipa_common_i.h
+++ b/drivers/platform/msm/ipa/ipa_common_i.h
@@ -12,6 +12,7 @@
#ifndef _IPA_COMMON_I_H_
#define _IPA_COMMON_I_H_
+#include <linux/ipc_logging.h>
#define __FILENAME__ \
(strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
@@ -114,6 +115,13 @@ struct ipa_active_client_logging_info {
extern const char *ipa_clients_strings[];
+#define IPA_IPC_LOGGING(buf, fmt, args...) \
+ do { \
+ if (buf) \
+ ipc_log_string((buf), fmt, __func__, __LINE__, \
+ ## args); \
+ } while (0)
+
void ipa_inc_client_enable_clks(struct ipa_active_client_logging_info *id);
void ipa_dec_client_disable_clks(struct ipa_active_client_logging_info *id);
int ipa_inc_client_enable_clks_no_block(
@@ -123,6 +131,8 @@ int ipa_resume_resource(enum ipa_rm_resource_name name);
int ipa_suspend_resource_sync(enum ipa_rm_resource_name resource);
int ipa_set_required_perf_profile(enum ipa_voltage_level floor_voltage,
u32 bandwidth_mbps);
+void *ipa_get_ipc_logbuf(void);
+void *ipa_get_ipc_logbuf_low(void);
#endif /* _IPA_COMMON_I_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_rm.c b/drivers/platform/msm/ipa/ipa_rm.c
index 53c72b154096..d0bde0e9654b 100644
--- a/drivers/platform/msm/ipa/ipa_rm.c
+++ b/drivers/platform/msm/ipa/ipa_rm.c
@@ -657,7 +657,7 @@ static void ipa_rm_wq_handler(struct work_struct *work)
container_of(work,
struct ipa_rm_wq_work_type,
work);
- IPA_RM_DBG("%s cmd=%d event=%d notify_registered_only=%d\n",
+ IPA_RM_DBG_LOW("%s cmd=%d event=%d notify_registered_only=%d\n",
ipa_rm_resource_str(ipa_rm_work->resource_name),
ipa_rm_work->wq_cmd,
ipa_rm_work->event,
@@ -714,7 +714,7 @@ static void ipa_rm_wq_resume_handler(struct work_struct *work)
container_of(work,
struct ipa_rm_wq_suspend_resume_work_type,
work);
- IPA_RM_DBG("resume work handler: %s",
+ IPA_RM_DBG_LOW("resume work handler: %s",
ipa_rm_resource_str(ipa_rm_work->resource_name));
if (!IPA_RM_RESORCE_IS_CONS(ipa_rm_work->resource_name)) {
@@ -750,7 +750,7 @@ static void ipa_rm_wq_suspend_handler(struct work_struct *work)
container_of(work,
struct ipa_rm_wq_suspend_resume_work_type,
work);
- IPA_RM_DBG("suspend work handler: %s",
+ IPA_RM_DBG_LOW("suspend work handler: %s",
ipa_rm_resource_str(ipa_rm_work->resource_name));
if (!IPA_RM_RESORCE_IS_CONS(ipa_rm_work->resource_name)) {
@@ -947,7 +947,7 @@ static void ipa_rm_perf_profile_notify_to_ipa_work(struct work_struct *work)
work);
int res;
- IPA_RM_DBG("calling to IPA driver. voltage %d bandwidth %d\n",
+ IPA_RM_DBG_LOW("calling to IPA driver. voltage %d bandwidth %d\n",
notify_work->volt, notify_work->bandwidth_mbps);
res = ipa_set_required_perf_profile(notify_work->volt,
@@ -957,7 +957,7 @@ static void ipa_rm_perf_profile_notify_to_ipa_work(struct work_struct *work)
goto bail;
}
- IPA_RM_DBG("IPA driver notified\n");
+ IPA_RM_DBG_LOW("IPA driver notified\n");
bail:
kfree(notify_work);
}
@@ -995,7 +995,7 @@ void ipa_rm_perf_profile_change(enum ipa_rm_resource_name resource_name)
u32 sum_bw_prod = 0;
u32 sum_bw_cons = 0;
- IPA_RM_DBG("%s\n", ipa_rm_resource_str(resource_name));
+ IPA_RM_DBG_LOW("%s\n", ipa_rm_resource_str(resource_name));
if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
resource_name,
@@ -1021,7 +1021,7 @@ void ipa_rm_perf_profile_change(enum ipa_rm_resource_name resource_name)
switch (resource->state) {
case IPA_RM_GRANTED:
case IPA_RM_REQUEST_IN_PROGRESS:
- IPA_RM_DBG("max_bw = %d, needed_bw = %d\n",
+ IPA_RM_DBG_LOW("max_bw = %d, needed_bw = %d\n",
resource->max_bw, resource->needed_bw);
*bw_ptr = min(resource->max_bw, resource->needed_bw);
ipa_rm_ctx->prof_vote.volt[resource_name] =
@@ -1039,7 +1039,7 @@ void ipa_rm_perf_profile_change(enum ipa_rm_resource_name resource_name)
WARN_ON(1);
return;
}
- IPA_RM_DBG("resource bandwidth: %d voltage: %d\n", *bw_ptr,
+ IPA_RM_DBG_LOW("resource bandwidth: %d voltage: %d\n", *bw_ptr,
resource->floor_voltage);
ipa_rm_ctx->prof_vote.curr_volt = IPA_VOLTAGE_UNSPECIFIED;
@@ -1057,17 +1057,17 @@ void ipa_rm_perf_profile_change(enum ipa_rm_resource_name resource_name)
for (i = 0; i < IPA_RM_RESOURCE_CONS_MAX; i++)
sum_bw_cons += ipa_rm_ctx->prof_vote.bw_cons[i];
- IPA_RM_DBG("all prod bandwidth: %d all cons bandwidth: %d\n",
+ IPA_RM_DBG_LOW("all prod bandwidth: %d all cons bandwidth: %d\n",
sum_bw_prod, sum_bw_cons);
ipa_rm_ctx->prof_vote.curr_bw = min(sum_bw_prod, sum_bw_cons);
if (ipa_rm_ctx->prof_vote.curr_volt == old_volt &&
ipa_rm_ctx->prof_vote.curr_bw == old_bw) {
- IPA_RM_DBG("same voting\n");
+ IPA_RM_DBG_LOW("same voting\n");
return;
}
- IPA_RM_DBG("new voting: voltage %d bandwidth %d\n",
+ IPA_RM_DBG_LOW("new voting: voltage %d bandwidth %d\n",
ipa_rm_ctx->prof_vote.curr_volt,
ipa_rm_ctx->prof_vote.curr_bw);
diff --git a/drivers/platform/msm/ipa/ipa_rm_i.h b/drivers/platform/msm/ipa/ipa_rm_i.h
index 65dbff66a6dd..e0c1582e8543 100644
--- a/drivers/platform/msm/ipa/ipa_rm_i.h
+++ b/drivers/platform/msm/ipa/ipa_rm_i.h
@@ -16,15 +16,36 @@
#include <linux/workqueue.h>
#include <linux/ipa.h>
#include "ipa_rm_resource.h"
+#include "ipa_common_i.h"
#define IPA_RM_DRV_NAME "ipa_rm"
#define IPA_RM_DBG_LOW(fmt, args...) \
- pr_debug(IPA_RM_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+ do { \
+ pr_debug(IPA_RM_DRV_NAME " %s:%d " fmt, __func__, __LINE__, \
+ ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_RM_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
#define IPA_RM_DBG(fmt, args...) \
- pr_debug(IPA_RM_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+ do { \
+ pr_debug(IPA_RM_DRV_NAME " %s:%d " fmt, __func__, __LINE__, \
+ ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPA_RM_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_RM_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+
#define IPA_RM_ERR(fmt, args...) \
- pr_err(IPA_RM_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+ do { \
+ pr_err(IPA_RM_DRV_NAME " %s:%d " fmt, __func__, __LINE__, \
+ ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPA_RM_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_RM_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
#define IPA_RM_RESOURCE_CONS_MAX \
(IPA_RM_RESOURCE_MAX - IPA_RM_RESOURCE_PROD_MAX)
diff --git a/drivers/platform/msm/ipa/ipa_rm_resource.c b/drivers/platform/msm/ipa/ipa_rm_resource.c
index 75424eb768f4..597598df6997 100644
--- a/drivers/platform/msm/ipa/ipa_rm_resource.c
+++ b/drivers/platform/msm/ipa/ipa_rm_resource.c
@@ -85,9 +85,9 @@ int ipa_rm_resource_consumer_release_work(
{
int driver_result;
- IPA_RM_DBG("calling driver CB\n");
+ IPA_RM_DBG_LOW("calling driver CB\n");
driver_result = consumer->release_resource();
- IPA_RM_DBG("driver CB returned with %d\n", driver_result);
+ IPA_RM_DBG_LOW("driver CB returned with %d\n", driver_result);
/*
* Treat IPA_RM_RELEASE_IN_PROGRESS as IPA_RM_RELEASED
* for CONS which remains in RELEASE_IN_PROGRESS.
@@ -120,9 +120,9 @@ int ipa_rm_resource_consumer_request_work(struct ipa_rm_resource_cons *consumer,
{
int driver_result;
- IPA_RM_DBG("calling driver CB\n");
+ IPA_RM_DBG_LOW("calling driver CB\n");
driver_result = consumer->request_resource();
- IPA_RM_DBG("driver CB returned with %d\n", driver_result);
+ IPA_RM_DBG_LOW("driver CB returned with %d\n", driver_result);
if (driver_result == 0) {
if (notify_completion) {
ipa_rm_resource_consumer_handle_cb(consumer,
@@ -151,7 +151,7 @@ int ipa_rm_resource_consumer_request(
enum ipa_rm_resource_state prev_state;
struct ipa_active_client_logging_info log_info;
- IPA_RM_DBG("%s state: %d\n",
+ IPA_RM_DBG_LOW("%s state: %d\n",
ipa_rm_resource_str(consumer->resource.name),
consumer->resource.state);
@@ -166,7 +166,7 @@ int ipa_rm_resource_consumer_request(
ipa_rm_resource_str(consumer->resource.name));
if (prev_state == IPA_RM_RELEASE_IN_PROGRESS ||
ipa_inc_client_enable_clks_no_block(&log_info) != 0) {
- IPA_RM_DBG("async resume work for %s\n",
+ IPA_RM_DBG_LOW("async resume work for %s\n",
ipa_rm_resource_str(consumer->resource.name));
ipa_rm_wq_send_resume_cmd(consumer->resource.name,
prev_state,
@@ -198,10 +198,10 @@ int ipa_rm_resource_consumer_request(
if (inc_usage_count)
consumer->usage_count++;
bail:
- IPA_RM_DBG("%s new state: %d\n",
+ IPA_RM_DBG_LOW("%s new state: %d\n",
ipa_rm_resource_str(consumer->resource.name),
consumer->resource.state);
- IPA_RM_DBG("EXIT with %d\n", result);
+ IPA_RM_DBG_LOW("EXIT with %d\n", result);
return result;
}
@@ -214,7 +214,7 @@ int ipa_rm_resource_consumer_release(
int result = 0;
enum ipa_rm_resource_state save_state;
- IPA_RM_DBG("%s state: %d\n",
+ IPA_RM_DBG_LOW("%s state: %d\n",
ipa_rm_resource_str(consumer->resource.name),
consumer->resource.state);
save_state = consumer->resource.state;
@@ -255,10 +255,10 @@ int ipa_rm_resource_consumer_release(
goto bail;
}
bail:
- IPA_RM_DBG("%s new state: %d\n",
+ IPA_RM_DBG_LOW("%s new state: %d\n",
ipa_rm_resource_str(consumer->resource.name),
consumer->resource.state);
- IPA_RM_DBG("EXIT with %d\n", result);
+ IPA_RM_DBG_LOW("EXIT with %d\n", result);
return result;
}
@@ -278,7 +278,7 @@ void ipa_rm_resource_producer_notify_clients(
{
struct ipa_rm_notification_info *reg_info;
- IPA_RM_DBG("%s event: %d notify_registered_only: %d\n",
+ IPA_RM_DBG_LOW("%s event: %d notify_registered_only: %d\n",
ipa_rm_resource_str(producer->resource.name),
event,
notify_registered_only);
@@ -287,12 +287,12 @@ void ipa_rm_resource_producer_notify_clients(
if (notify_registered_only && !reg_info->explicit)
continue;
- IPA_RM_DBG("Notifying %s event: %d\n",
+ IPA_RM_DBG_LOW("Notifying %s event: %d\n",
ipa_rm_resource_str(producer->resource.name), event);
reg_info->reg_params.notify_cb(reg_info->reg_params.user_data,
event,
0);
- IPA_RM_DBG("back from client CB\n");
+ IPA_RM_DBG_LOW("back from client CB\n");
}
}
@@ -823,7 +823,7 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer)
}
unlock_and_bail:
if (state != producer->resource.state)
- IPA_RM_DBG("%s state changed %d->%d\n",
+ IPA_RM_DBG_LOW("%s state changed %d->%d\n",
ipa_rm_resource_str(producer->resource.name),
state,
producer->resource.state);
@@ -889,7 +889,7 @@ int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer)
}
bail:
if (state != producer->resource.state)
- IPA_RM_DBG("%s state changed %d->%d\n",
+ IPA_RM_DBG_LOW("%s state changed %d->%d\n",
ipa_rm_resource_str(producer->resource.name),
state,
producer->resource.state);
@@ -901,7 +901,7 @@ static void ipa_rm_resource_producer_handle_cb(
struct ipa_rm_resource_prod *producer,
enum ipa_rm_event event)
{
- IPA_RM_DBG("%s state: %d event: %d pending_request: %d\n",
+ IPA_RM_DBG_LOW("%s state: %d event: %d pending_request: %d\n",
ipa_rm_resource_str(producer->resource.name),
producer->resource.state,
event,
@@ -950,7 +950,7 @@ static void ipa_rm_resource_producer_handle_cb(
goto unlock_and_bail;
}
unlock_and_bail:
- IPA_RM_DBG("%s new state: %d\n",
+ IPA_RM_DBG_LOW("%s new state: %d\n",
ipa_rm_resource_str(producer->resource.name),
producer->resource.state);
bail:
@@ -973,7 +973,7 @@ void ipa_rm_resource_consumer_handle_cb(struct ipa_rm_resource_cons *consumer,
IPA_RM_ERR("invalid params\n");
return;
}
- IPA_RM_DBG("%s state: %d event: %d\n",
+ IPA_RM_DBG_LOW("%s state: %d event: %d\n",
ipa_rm_resource_str(consumer->resource.name),
consumer->resource.state,
event);
@@ -1013,7 +1013,7 @@ void ipa_rm_resource_consumer_handle_cb(struct ipa_rm_resource_cons *consumer,
return;
bail:
- IPA_RM_DBG("%s new state: %d\n",
+ IPA_RM_DBG_LOW("%s new state: %d\n",
ipa_rm_resource_str(consumer->resource.name),
consumer->resource.state);
}
@@ -1040,7 +1040,7 @@ int ipa_rm_resource_set_perf_profile(struct ipa_rm_resource *resource,
}
if (profile->max_supported_bandwidth_mbps == resource->max_bw) {
- IPA_RM_DBG("same profile\n");
+ IPA_RM_DBG_LOW("same profile\n");
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
index 6cfa477608b5..2255a74331cb 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
@@ -497,7 +497,7 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
}
} else {
tx_pkt->mem.base = desc[i].frag;
- tx_pkt->mem.size = skb_frag_size(desc[i].frag);
+ tx_pkt->mem.size = desc[i].len;
if (!desc[i].dma_address_valid) {
tx_pkt->mem.phys_base =
@@ -1634,6 +1634,7 @@ int ipa2_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
for (f = 0; f < num_frags; f++) {
desc[2+f].frag = &skb_shinfo(skb)->frags[f];
desc[2+f].type = IPA_DATA_DESC_SKB_PAGED;
+ desc[2+f].len = skb_frag_size(desc[2+f].frag);
}
/* don't free skb till frag mappings are released */
@@ -1673,6 +1674,7 @@ int ipa2_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
for (f = 0; f < num_frags; f++) {
desc[1+f].frag = &skb_shinfo(skb)->frags[f];
desc[1+f].type = IPA_DATA_DESC_SKB_PAGED;
+ desc[1+f].len = skb_frag_size(desc[1+f].frag);
}
/* don't free skb till frag mappings are released */
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
index 7a8318a6e138..00f18333587b 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
@@ -854,11 +854,6 @@ static int ipa_q6_clnt_svc_event_notify(struct notifier_block *this,
queue_delayed_work(ipa_clnt_req_workqueue,
&work_svc_arrive, 0);
break;
- case QMI_SERVER_EXIT:
- if (!atomic_read(&workqueues_stopped))
- queue_delayed_work(ipa_clnt_req_workqueue,
- &work_svc_exit, 0);
- break;
default:
break;
}
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
index fe315bd1e4b1..6fd9b4e61e02 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
@@ -4936,6 +4936,18 @@ static int ipa2_stop_gsi_channel(u32 clnt_hdl)
return -EFAULT;
}
+static void *ipa2_get_ipc_logbuf(void)
+{
+ /* no support for IPC logging in IPAv2 */
+ return NULL;
+}
+
+static void *ipa2_get_ipc_logbuf_low(void)
+{
+ /* no support for IPC logging in IPAv2 */
+ return NULL;
+}
+
int ipa2_bind_api_controller(enum ipa_hw_type ipa_hw_type,
struct ipa_api_controller *api_ctrl)
@@ -5072,6 +5084,9 @@ int ipa2_bind_api_controller(enum ipa_hw_type ipa_hw_type,
api_ctrl->ipa_suspend_resource_sync = ipa2_suspend_resource_sync;
api_ctrl->ipa_set_required_perf_profile =
ipa2_set_required_perf_profile;
+ api_ctrl->ipa_get_ipc_logbuf = ipa2_get_ipc_logbuf;
+ api_ctrl->ipa_get_ipc_logbuf_low = ipa2_get_ipc_logbuf_low;
+
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index a8036602ec2f..322fe1fe6de8 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -67,8 +67,6 @@
#define IPA_TRANSPORT_PROD_TIMEOUT_MSEC 100
-#define IPA_IPC_LOG_PAGES 50
-
#define IPA3_ACTIVE_CLIENTS_TABLE_BUF_SIZE 2048
#define IPA3_ACTIVE_CLIENT_LOG_TYPE_EP 0
@@ -3958,13 +3956,6 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
result = -ENOMEM;
goto fail_logbuf;
}
- ipa3_ctx->logbuf_low =
- ipc_log_context_create(IPA_IPC_LOG_PAGES, "ipa_low", 0);
- if (ipa3_ctx->logbuf_low == NULL) {
- IPAERR("failed to get logbuf_low\n");
- result = -ENOMEM;
- goto fail_logbuf_low;
- }
ipa3_ctx->pdev = ipa_dev;
ipa3_ctx->uc_pdev = ipa_dev;
@@ -4460,8 +4451,6 @@ fail_bus_reg:
fail_bind:
kfree(ipa3_ctx->ctrl);
fail_mem_ctrl:
- ipc_log_context_destroy(ipa3_ctx->logbuf_low);
-fail_logbuf_low:
ipc_log_context_destroy(ipa3_ctx->logbuf);
fail_logbuf:
kfree(ipa3_ctx);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
index f4e17074f409..f5f5cdae0e32 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
@@ -1152,7 +1152,8 @@ int ipa3_request_gsi_channel(struct ipa_request_gsi_channel_params *params,
memcpy(&ep->chan_scratch, &params->chan_scratch,
sizeof(union __packed gsi_channel_scratch));
- ep->chan_scratch.xdci.max_outstanding_tre = gsi_ep_cfg_ptr->ipa_if_aos;
+ ep->chan_scratch.xdci.max_outstanding_tre =
+ params->chan_params.re_size * gsi_ep_cfg_ptr->ipa_if_tlv;
gsi_res = gsi_write_channel_scratch(ep->gsi_chan_hdl,
params->chan_scratch);
if (gsi_res != GSI_STATUS_SUCCESS) {
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
index 96832869a496..0ca7b662aa17 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
@@ -1587,6 +1587,43 @@ static ssize_t ipa3_clear_active_clients_log(struct file *file,
return count;
}
+static ssize_t ipa3_enable_ipc_low(struct file *file,
+ const char __user *ubuf, size_t count, loff_t *ppos)
+{
+ unsigned long missing;
+ s8 option = 0;
+
+ if (sizeof(dbg_buff) < count + 1)
+ return -EFAULT;
+
+ missing = copy_from_user(dbg_buff, ubuf, count);
+ if (missing)
+ return -EFAULT;
+
+ dbg_buff[count] = '\0';
+ if (kstrtos8(dbg_buff, 0, &option))
+ return -EFAULT;
+
+ if (option) {
+ if (!ipa3_ctx->logbuf_low) {
+ ipa3_ctx->logbuf_low =
+ ipc_log_context_create(IPA_IPC_LOG_PAGES,
+ "ipa_low", 0);
+ }
+
+ if (ipa3_ctx->logbuf_low == NULL) {
+ IPAERR("failed to get logbuf_low\n");
+ return -EFAULT;
+ }
+ } else {
+ if (ipa3_ctx->logbuf_low)
+ ipc_log_context_destroy(ipa3_ctx->logbuf_low);
+ ipa3_ctx->logbuf_low = NULL;
+ }
+
+ return count;
+}
+
const struct file_operations ipa3_gen_reg_ops = {
.read = ipa3_read_gen_reg,
};
@@ -1671,6 +1708,10 @@ const struct file_operations ipa3_active_clients = {
.write = ipa3_clear_active_clients_log,
};
+const struct file_operations ipa3_ipc_low_ops = {
+ .write = ipa3_enable_ipc_low,
+};
+
void ipa3_debugfs_init(void)
{
const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH;
@@ -1883,8 +1924,8 @@ void ipa3_debugfs_init(void)
goto fail;
}
- file = debugfs_create_u32("enable_low_prio_print", read_write_mode,
- dent, &ipa3_ctx->enable_low_prio_print);
+ file = debugfs_create_file("enable_low_prio_print", write_only_mode,
+ dent, 0, &ipa3_ipc_low_ops);
if (!file) {
IPAERR("could not create enable_low_prio_print file\n");
goto fail;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dma.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dma.c
index 966f279d863b..9d1ff18d7ed0 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dma.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -33,16 +33,38 @@
#define IPADMA_DRV_NAME "ipa_dma"
#define IPADMA_DBG(fmt, args...) \
- pr_debug(IPADMA_DRV_NAME " %s:%d " fmt, \
- __func__, __LINE__, ## args)
+ do { \
+ pr_debug(IPADMA_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPADMA_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPADMA_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+
+#define IPADMA_DBG_LOW(fmt, args...) \
+ do { \
+ pr_debug(IPADMA_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPADMA_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+
#define IPADMA_ERR(fmt, args...) \
- pr_err(IPADMA_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+ do { \
+ pr_err(IPADMA_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPADMA_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPADMA_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
#define IPADMA_FUNC_ENTRY() \
- IPADMA_DBG("ENTRY\n")
+ IPADMA_DBG_LOW("ENTRY\n")
#define IPADMA_FUNC_EXIT() \
- IPADMA_DBG("EXIT\n")
+ IPADMA_DBG_LOW("EXIT\n")
#ifdef CONFIG_DEBUG_FS
#define IPADMA_MAX_MSG_LEN 1024
@@ -255,7 +277,7 @@ int ipa3_dma_enable(void)
}
mutex_lock(&ipa3_dma_ctx->enable_lock);
if (ipa3_dma_ctx->is_enabled) {
- IPADMA_DBG("Already enabled.\n");
+ IPADMA_ERR("Already enabled.\n");
mutex_unlock(&ipa3_dma_ctx->enable_lock);
return -EPERM;
}
@@ -281,7 +303,7 @@ static bool ipa3_dma_work_pending(void)
IPADMA_DBG("pending uc\n");
return true;
}
- IPADMA_DBG("no pending work\n");
+ IPADMA_DBG_LOW("no pending work\n");
return false;
}
@@ -309,7 +331,7 @@ int ipa3_dma_disable(void)
mutex_lock(&ipa3_dma_ctx->enable_lock);
spin_lock_irqsave(&ipa3_dma_ctx->pending_lock, flags);
if (!ipa3_dma_ctx->is_enabled) {
- IPADMA_DBG("Already disabled.\n");
+ IPADMA_ERR("Already disabled.\n");
spin_unlock_irqrestore(&ipa3_dma_ctx->pending_lock, flags);
mutex_unlock(&ipa3_dma_ctx->enable_lock);
return -EPERM;
@@ -358,7 +380,7 @@ int ipa3_dma_sync_memcpy(u64 dest, u64 src, int len)
bool stop_polling = false;
IPADMA_FUNC_ENTRY();
- IPADMA_DBG("input parameters: dest = 0x%llx, src = 0x%llx, len = %d\n",
+ IPADMA_DBG_LOW("dest = 0x%llx, src = 0x%llx, len = %d\n",
dest, src, len);
if (ipa3_dma_ctx == NULL) {
IPADMA_ERR("IPADMA isn't initialized, can't memcpy\n");
@@ -390,7 +412,7 @@ int ipa3_dma_sync_memcpy(u64 dest, u64 src, int len)
if (atomic_read(&ipa3_dma_ctx->sync_memcpy_pending_cnt) >=
IPA_DMA_MAX_PENDING_SYNC) {
atomic_dec(&ipa3_dma_ctx->sync_memcpy_pending_cnt);
- IPADMA_DBG("Reached pending requests limit\n");
+ IPADMA_ERR("Reached pending requests limit\n");
return -EFAULT;
}
}
@@ -575,7 +597,7 @@ int ipa3_dma_async_memcpy(u64 dest, u64 src, int len,
unsigned long flags;
IPADMA_FUNC_ENTRY();
- IPADMA_DBG("input parameters: dest = 0x%llx, src = 0x%llx, len = %d\n",
+ IPADMA_DBG_LOW("dest = 0x%llx, src = 0x%llx, len = %d\n",
dest, src, len);
if (ipa3_dma_ctx == NULL) {
IPADMA_ERR("IPADMA isn't initialized, can't memcpy\n");
@@ -612,7 +634,7 @@ int ipa3_dma_async_memcpy(u64 dest, u64 src, int len,
if (atomic_read(&ipa3_dma_ctx->async_memcpy_pending_cnt) >=
IPA_DMA_MAX_PENDING_ASYNC) {
atomic_dec(&ipa3_dma_ctx->async_memcpy_pending_cnt);
- IPADMA_DBG("Reached pending requests limit\n");
+ IPADMA_ERR("Reached pending requests limit\n");
return -EFAULT;
}
}
@@ -774,7 +796,7 @@ void ipa3_dma_destroy(void)
IPADMA_FUNC_ENTRY();
if (!ipa3_dma_ctx) {
- IPADMA_DBG("IPADMA isn't initialized\n");
+ IPADMA_ERR("IPADMA isn't initialized\n");
return;
}
@@ -919,7 +941,7 @@ static ssize_t ipa3_dma_debugfs_reset_statistics(struct file *file,
switch (in_num) {
case 0:
if (ipa3_dma_work_pending())
- IPADMA_DBG("Note, there are pending memcpy\n");
+ IPADMA_ERR("Note, there are pending memcpy\n");
atomic_set(&ipa3_dma_ctx->total_async_memcpy, 0);
atomic_set(&ipa3_dma_ctx->total_sync_memcpy, 0);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index 73961224f441..5e67101a987f 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -52,7 +52,6 @@
#define IPA_SIZE_DL_CSUM_META_TRAILER 8
#define IPA_GSI_EVT_RING_LEN 4096
-#define IPA_GSI_CHANNEL_RING_LEN 4096
#define IPA_GSI_MAX_CH_LOW_WEIGHT 15
#define IPA_GSI_EVT_RING_INT_MODT 3200 /* 0.1s under 32KHz clock */
@@ -75,7 +74,8 @@ static void ipa3_cleanup_wlan_rx_common_cache(void);
static void ipa3_wq_repl_rx(struct work_struct *work);
static void ipa3_dma_memcpy_notify(struct ipa3_sys_context *sys,
struct ipa3_mem_buffer *mem_info);
-static int ipa_gsi_setup_channel(struct ipa3_ep_context *ep);
+static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
+ struct ipa3_ep_context *ep);
static int ipa_populate_tag_field(struct ipa3_desc *desc,
struct ipa3_tx_pkt_wrapper *tx_pkt,
struct ipahal_imm_cmd_pyld **tag_pyld_ret);
@@ -1174,7 +1174,7 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
}
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
- result = ipa_gsi_setup_channel(ep);
+ result = ipa_gsi_setup_channel(sys_in, ep);
if (result) {
IPAERR("Failed to setup GSI channel\n");
goto fail_gen2;
@@ -3569,7 +3569,8 @@ static void ipa_dma_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify)
}
-static int ipa_gsi_setup_channel(struct ipa3_ep_context *ep)
+static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
+ struct ipa3_ep_context *ep)
{
struct gsi_evt_ring_props gsi_evt_ring_props;
struct gsi_chan_props gsi_channel_props;
@@ -3642,10 +3643,19 @@ static int ipa_gsi_setup_channel(struct ipa3_ep_context *ep)
gsi_channel_props.evt_ring_hdl = ep->gsi_evt_ring_hdl;
gsi_channel_props.re_size = GSI_CHAN_RE_SIZE_16B;
- gsi_channel_props.ring_len = IPA_GSI_CHANNEL_RING_LEN;
+ /*
+ * GSI ring length is calculated based on the desc_fifo_sz which was
+ * meant to define the BAM desc fifo. GSI descriptors are 16B as opposed
+ * to 8B for BAM. For PROD pipes there is also an additional descriptor
+ * for TAG STATUS immediate command.
+ */
+ if (IPA_CLIENT_IS_PROD(ep->client))
+ gsi_channel_props.ring_len = 4 * in->desc_fifo_sz;
+ else
+ gsi_channel_props.ring_len = 2 * in->desc_fifo_sz;
gsi_channel_props.ring_base_vaddr =
- dma_alloc_coherent(ipa3_ctx->pdev, IPA_GSI_CHANNEL_RING_LEN,
- &dma_addr, 0);
+ dma_alloc_coherent(ipa3_ctx->pdev, gsi_channel_props.ring_len,
+ &dma_addr, 0);
gsi_channel_props.ring_base_addr = dma_addr;
/* copy mem info */
@@ -3655,7 +3665,7 @@ static int ipa_gsi_setup_channel(struct ipa3_ep_context *ep)
ep->gsi_mem_info.chan_ring_base_vaddr =
gsi_channel_props.ring_base_vaddr;
- gsi_channel_props.use_db_eng = GSI_CHAN_DIRECT_MODE;
+ gsi_channel_props.use_db_eng = GSI_CHAN_DB_MODE;
gsi_channel_props.max_prefetch = GSI_ONE_PREFETCH_SEG;
if (ep->client == IPA_CLIENT_APPS_CMD_PROD)
gsi_channel_props.low_weight = IPA_GSI_MAX_CH_LOW_WEIGHT;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
index f58751d4c0d3..bb94b95eabb9 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
@@ -22,12 +22,6 @@ static const u32 ipa_hdr_proc_ctx_bin_sz[IPA_HDR_PROC_CTX_BIN_MAX] = { 32, 64};
#define HDR_PROC_TYPE_IS_VALID(type) \
((type) >= 0 && (type) < IPA_HDR_PROC_MAX)
-/* uCP command numbers */
-#define IPA_HDR_UCP_802_3_TO_802_3 6
-#define IPA_HDR_UCP_802_3_TO_ETHII 7
-#define IPA_HDR_UCP_ETHII_TO_802_3 8
-#define IPA_HDR_UCP_ETHII_TO_ETHII 9
-
/**
* ipa3_generate_hdr_hw_tbl() - generates the headers table
* @mem: [out] buffer to put the header table
@@ -60,8 +54,8 @@ static int ipa3_generate_hdr_hw_tbl(struct ipa3_mem_buffer *mem)
continue;
IPADBG_LOW("hdr of len %d ofst=%d\n", entry->hdr_len,
entry->offset_entry->offset);
- memcpy(mem->base + entry->offset_entry->offset, entry->hdr,
- entry->hdr_len);
+ ipahal_cp_hdr_to_hw_buff(mem->base, entry->offset_entry->offset,
+ entry->hdr, entry->hdr_len);
}
return 0;
@@ -77,52 +71,13 @@ static void ipa3_hdr_proc_ctx_to_hw_format(struct ipa3_mem_buffer *mem,
link) {
IPADBG_LOW("processing type %d ofst=%d\n",
entry->type, entry->offset_entry->offset);
- if (entry->type == IPA_HDR_PROC_NONE) {
- struct ipa3_hdr_proc_ctx_add_hdr_seq *ctx;
-
- ctx = (struct ipa3_hdr_proc_ctx_add_hdr_seq *)
- (mem->base + entry->offset_entry->offset);
- ctx->hdr_add.tlv.type = IPA_PROC_CTX_TLV_TYPE_HDR_ADD;
- ctx->hdr_add.tlv.length = 1;
- ctx->hdr_add.tlv.value = entry->hdr->hdr_len;
- ctx->hdr_add.hdr_addr = (entry->hdr->is_hdr_proc_ctx) ?
- entry->hdr->phys_base :
- hdr_base_addr +
- entry->hdr->offset_entry->offset;
- IPADBG_LOW("header address 0x%x\n",
- ctx->hdr_add.hdr_addr);
- ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END;
- ctx->end.length = 0;
- ctx->end.value = 0;
- } else {
- struct ipa3_hdr_proc_ctx_add_hdr_cmd_seq *ctx;
-
- ctx = (struct ipa3_hdr_proc_ctx_add_hdr_cmd_seq *)
- (mem->base + entry->offset_entry->offset);
- ctx->hdr_add.tlv.type = IPA_PROC_CTX_TLV_TYPE_HDR_ADD;
- ctx->hdr_add.tlv.length = 1;
- ctx->hdr_add.tlv.value = entry->hdr->hdr_len;
- ctx->hdr_add.hdr_addr = (entry->hdr->is_hdr_proc_ctx) ?
- entry->hdr->phys_base :
- hdr_base_addr +
- entry->hdr->offset_entry->offset;
- IPADBG_LOW("header address 0x%x\n",
- ctx->hdr_add.hdr_addr);
- ctx->cmd.type = IPA_PROC_CTX_TLV_TYPE_PROC_CMD;
- ctx->cmd.length = 0;
- if (entry->type == IPA_HDR_PROC_ETHII_TO_ETHII)
- ctx->cmd.value = IPA_HDR_UCP_ETHII_TO_ETHII;
- else if (entry->type == IPA_HDR_PROC_ETHII_TO_802_3)
- ctx->cmd.value = IPA_HDR_UCP_ETHII_TO_802_3;
- else if (entry->type == IPA_HDR_PROC_802_3_TO_ETHII)
- ctx->cmd.value = IPA_HDR_UCP_802_3_TO_ETHII;
- else if (entry->type == IPA_HDR_PROC_802_3_TO_802_3)
- ctx->cmd.value = IPA_HDR_UCP_802_3_TO_802_3;
- IPADBG_LOW("command id %d\n", ctx->cmd.value);
- ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END;
- ctx->end.length = 0;
- ctx->end.value = 0;
- }
+ ipahal_cp_proc_ctx_to_hw_buff(entry->type, mem->base,
+ entry->offset_entry->offset,
+ entry->hdr->hdr_len,
+ entry->hdr->is_hdr_proc_ctx,
+ entry->hdr->phys_base,
+ hdr_base_addr,
+ entry->hdr->offset_entry->offset);
}
}
@@ -395,9 +350,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
hdr_entry->ref_cnt++;
entry->cookie = IPA_COOKIE;
- needed_len = (proc_ctx->type == IPA_HDR_PROC_NONE) ?
- sizeof(struct ipa3_hdr_proc_ctx_add_hdr_seq) :
- sizeof(struct ipa3_hdr_proc_ctx_add_hdr_cmd_seq);
+ needed_len = ipahal_get_proc_ctx_needed_len(proc_ctx->type);
if (needed_len <= ipa_hdr_proc_ctx_bin_sz[IPA_HDR_PROC_CTX_BIN0]) {
bin = IPA_HDR_PROC_CTX_BIN0;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hw_defs.h b/drivers/platform/msm/ipa/ipa_v3/ipa_hw_defs.h
index 1b732efe2b2c..38a63f8a67ba 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_hw_defs.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hw_defs.h
@@ -16,11 +16,6 @@
/* This header defines various HW related data types */
-/* Processing context TLV type */
-#define IPA_PROC_CTX_TLV_TYPE_END 0
-#define IPA_PROC_CTX_TLV_TYPE_HDR_ADD 1
-#define IPA_PROC_CTX_TLV_TYPE_PROC_CMD 3
-
#define IPA_RULE_ID_INVALID 0x3FF
/**
@@ -94,40 +89,6 @@ struct ipa3_rt_rule_hw_hdr {
} u;
};
-/**
- * struct ipa3_hdr_proc_ctx_tlv -
- * HW structure of IPA processing context header - TLV part
- * @type: 0 - end type
- * 1 - header addition type
- * 3 - processing command type
- * @length: number of bytes after tlv
- * for type:
- * 0 - needs to be 0
- * 1 - header addition length
- * 3 - number of 32B including type and length.
- * @value: specific value for type
- * for type:
- * 0 - needs to be 0
- * 1 - header length
- * 3 - command ID (see IPA_HDR_UCP_* definitions)
- */
-struct ipa3_hdr_proc_ctx_tlv {
- u32 type:8;
- u32 length:8;
- u32 value:16;
-};
-
-/**
- * struct ipa3_hdr_proc_ctx_hdr_add -
- * HW structure of IPA processing context - add header tlv
- * @tlv: IPA processing context TLV
- * @hdr_addr: processing context header address
- */
-struct ipa3_hdr_proc_ctx_hdr_add {
- struct ipa3_hdr_proc_ctx_tlv tlv;
- u32 hdr_addr;
-};
-
#define IPA_A5_MUX_HDR_EXCP_FLAG_IP BIT(7)
#define IPA_A5_MUX_HDR_EXCP_FLAG_NAT BIT(6)
#define IPA_A5_MUX_HDR_EXCP_FLAG_SW_FLT BIT(5)
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 62c764d29171..cec83ef7a202 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -27,7 +27,6 @@
#include <asm/dma-iommu.h>
#include <linux/iommu.h>
#include <linux/platform_device.h>
-#include <linux/ipc_logging.h>
#include <linux/firmware.h>
#include "ipa_hw_defs.h"
#include "ipa_ram_mmap.h"
@@ -56,32 +55,35 @@
#define IPA_MAX_STATUS_STAT_NUM 30
-#define IPA_IPC_LOGGING(buf, fmt, args...) \
- ipc_log_string((buf), \
- DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+#define IPA_IPC_LOG_PAGES 50
#define IPADBG(fmt, args...) \
do { \
pr_debug(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args);\
if (ipa3_ctx) { \
- IPA_IPC_LOGGING(ipa3_ctx->logbuf, fmt, ## args); \
- IPA_IPC_LOGGING(ipa3_ctx->logbuf_low, fmt, ## args); \
+ IPA_IPC_LOGGING(ipa3_ctx->logbuf, \
+ DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa3_ctx->logbuf_low, \
+ DRV_NAME " %s:%d " fmt, ## args); \
} \
} while (0)
#define IPADBG_LOW(fmt, args...) \
do { \
pr_debug(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args);\
- if (ipa3_ctx && ipa3_ctx->enable_low_prio_print) \
- IPA_IPC_LOGGING(ipa3_ctx->logbuf_low, fmt, ## args); \
+ if (ipa3_ctx) \
+ IPA_IPC_LOGGING(ipa3_ctx->logbuf_low, \
+ DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define IPAERR(fmt, args...) \
do { \
pr_err(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args);\
if (ipa3_ctx) { \
- IPA_IPC_LOGGING(ipa3_ctx->logbuf, fmt, ## args); \
- IPA_IPC_LOGGING(ipa3_ctx->logbuf_low, fmt, ## args); \
+ IPA_IPC_LOGGING(ipa3_ctx->logbuf, \
+ DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa3_ctx->logbuf_low, \
+ DRV_NAME " %s:%d " fmt, ## args); \
} \
} while (0)
@@ -394,30 +396,6 @@ struct ipa3_hdr_proc_ctx_offset_entry {
};
/**
- * struct ipa3_hdr_proc_ctx_add_hdr_seq -
- * IPA processing context header - add header sequence
- * @hdr_add: add header command
- * @end: tlv end command (cmd.type must be 0)
- */
-struct ipa3_hdr_proc_ctx_add_hdr_seq {
- struct ipa3_hdr_proc_ctx_hdr_add hdr_add;
- struct ipa3_hdr_proc_ctx_tlv end;
-};
-
-/**
- * struct ipa3_hdr_proc_ctx_add_hdr_cmd_seq -
- * IPA processing context header - process command sequence
- * @hdr_add: add header command
- * @cmd: tlv processing command (cmd.type must be 3)
- * @end: tlv end command (cmd.type must be 0)
- */
-struct ipa3_hdr_proc_ctx_add_hdr_cmd_seq {
- struct ipa3_hdr_proc_ctx_hdr_add hdr_add;
- struct ipa3_hdr_proc_ctx_tlv cmd;
- struct ipa3_hdr_proc_ctx_tlv end;
-};
-
-/**
struct ipa3_hdr_proc_ctx_entry - IPA processing context header table entry
* @link: entry's link in global header table entries list
* @type:
@@ -1432,7 +1410,6 @@ struct ipa3_ready_cb_info {
* @ctrl: holds the core specific operations based on
* core version (vtable like)
* @enable_clock_scaling: clock scaling is enabled ?
- * @enable_low_prio_print: enable low priority prints
* @curr_ipa_clk_rate: ipa3_clk current rate
* @wcstats: wlan common buffer stats
* @uc_ctx: uC interface context
@@ -1537,7 +1514,6 @@ struct ipa3_context {
struct device *uc_pdev;
spinlock_t idr_lock;
u32 enable_clock_scaling;
- u32 enable_low_prio_print;
u32 curr_ipa_clk_rate;
bool q6_proxy_clk_vote_valid;
u32 ipa_num_pipes;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c b/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c
index 45d3b13049bc..ca022b6332dd 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c
@@ -413,12 +413,6 @@ int ipa3_remove_interrupt_handler(enum ipa_irq_type interrupt)
return -EFAULT;
}
- kfree(ipa_interrupt_to_cb[irq_num].private_data);
- ipa_interrupt_to_cb[irq_num].deferred_flag = false;
- ipa_interrupt_to_cb[irq_num].handler = NULL;
- ipa_interrupt_to_cb[irq_num].private_data = NULL;
- ipa_interrupt_to_cb[irq_num].interrupt = -1;
-
/* clean SUSPEND_IRQ_EN_EE_n_ADDR for L2 interrupt */
if ((interrupt == IPA_TX_SUSPEND_IRQ) &&
(ipa3_ctx->ipa_hw_type == IPA_HW_v3_1)) {
@@ -431,6 +425,13 @@ int ipa3_remove_interrupt_handler(enum ipa_irq_type interrupt)
val &= ~bmsk;
ipa3_uc_rg10_write_reg(IPA_IRQ_EN_EE_n, ipa_ee, val);
+ /* delete the handlers after clean-up interrupts */
+ kfree(ipa_interrupt_to_cb[irq_num].private_data);
+ ipa_interrupt_to_cb[irq_num].deferred_flag = false;
+ ipa_interrupt_to_cb[irq_num].handler = NULL;
+ ipa_interrupt_to_cb[irq_num].private_data = NULL;
+ ipa_interrupt_to_cb[irq_num].interrupt = -1;
+
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c
index 82f63d3cf5a5..517093adbe81 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c
@@ -21,15 +21,42 @@
#include "ipa_qmi_service.h"
#define IPA_MHI_DRV_NAME "ipa_mhi"
+
+
#define IPA_MHI_DBG(fmt, args...) \
- pr_debug(IPA_MHI_DRV_NAME " %s:%d " fmt, \
- __func__, __LINE__, ## args)
+ do { \
+ pr_debug(IPA_MHI_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPA_MHI_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_MHI_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+
+#define IPA_MHI_DBG_LOW(fmt, args...) \
+ do { \
+ pr_debug(IPA_MHI_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_MHI_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+
+
#define IPA_MHI_ERR(fmt, args...) \
- pr_err(IPA_MHI_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+ do { \
+ pr_err(IPA_MHI_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPA_MHI_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_MHI_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+
+
#define IPA_MHI_FUNC_ENTRY() \
- IPA_MHI_DBG("ENTRY\n")
+ IPA_MHI_DBG_LOW("ENTRY\n")
#define IPA_MHI_FUNC_EXIT() \
- IPA_MHI_DBG("EXIT\n")
+ IPA_MHI_DBG_LOW("EXIT\n")
#define IPA_MHI_GSI_ER_START 10
#define IPA_MHI_GSI_ER_END 16
@@ -756,12 +783,12 @@ static void ipa3_mhi_rm_prod_notify(void *user_data, enum ipa_rm_event event,
switch (event) {
case IPA_RM_RESOURCE_GRANTED:
- IPA_MHI_DBG("IPA_RM_RESOURCE_GRANTED\n");
+ IPA_MHI_DBG_LOW("IPA_RM_RESOURCE_GRANTED\n");
complete_all(&ipa3_mhi_ctx->rm_prod_granted_comp);
break;
case IPA_RM_RESOURCE_RELEASED:
- IPA_MHI_DBG("IPA_RM_RESOURCE_RELEASED\n");
+ IPA_MHI_DBG_LOW("IPA_RM_RESOURCE_RELEASED\n");
break;
default:
@@ -828,7 +855,7 @@ static int ipa3_mhi_rm_cons_request(void)
}
spin_unlock_irqrestore(&ipa3_mhi_ctx->state_lock, flags);
- IPA_MHI_DBG("EXIT with %d\n", res);
+ IPA_MHI_DBG_LOW("EXIT with %d\n", res);
return res;
}
@@ -878,7 +905,7 @@ static int ipa3_mhi_request_prod(void)
IPA_MHI_FUNC_ENTRY();
reinit_completion(&ipa3_mhi_ctx->rm_prod_granted_comp);
- IPA_MHI_DBG("requesting mhi prod\n");
+ IPA_MHI_DBG_LOW("requesting mhi prod\n");
res = ipa_rm_request_resource(IPA_RM_RESOURCE_MHI_PROD);
if (res) {
if (res != -EINPROGRESS) {
@@ -894,7 +921,7 @@ static int ipa3_mhi_request_prod(void)
}
}
- IPA_MHI_DBG("mhi prod granted\n");
+ IPA_MHI_DBG_LOW("mhi prod granted\n");
IPA_MHI_FUNC_EXIT();
return 0;
@@ -1071,11 +1098,12 @@ static bool ipa3_mhi_gsi_channel_empty(struct ipa3_mhi_channel_ctx *channel)
IPA_MHI_FUNC_ENTRY();
if (!channel->stop_in_proc) {
- IPA_MHI_DBG("Channel is not in STOP_IN_PROC\n");
+ IPA_MHI_DBG_LOW("Channel is not in STOP_IN_PROC\n");
return true;
}
- IPA_MHI_DBG("Stopping GSI channel %ld\n", channel->ep->gsi_chan_hdl);
+ IPA_MHI_DBG_LOW("Stopping GSI channel %ld\n",
+ channel->ep->gsi_chan_hdl);
res = gsi_stop_channel(channel->ep->gsi_chan_hdl);
if (res != 0 &&
res != -GSI_STATUS_AGAIN &&
@@ -1087,7 +1115,7 @@ static bool ipa3_mhi_gsi_channel_empty(struct ipa3_mhi_channel_ctx *channel)
}
if (res == 0) {
- IPA_MHI_DBG("GSI channel %ld STOP\n",
+ IPA_MHI_DBG_LOW("GSI channel %ld STOP\n",
channel->ep->gsi_chan_hdl);
channel->stop_in_proc = false;
return true;
@@ -1129,7 +1157,7 @@ static bool ipa3_mhi_wait_for_ul_empty_timeout(unsigned int msecs)
}
if (time_after(jiffies, jiffies_start + jiffies_timeout)) {
- IPA_MHI_DBG("timeout waiting for UL empty\n");
+ IPA_MHI_DBG_LOW("timeout waiting for UL empty\n");
break;
}
@@ -1441,31 +1469,31 @@ static int ipa_mhi_start_uc_channel(struct ipa3_mhi_channel_ctx *channel,
static void ipa_mhi_dump_ch_ctx(struct ipa3_mhi_channel_ctx *channel)
{
- IPA_MHI_DBG("ch_id %d\n", channel->id);
- IPA_MHI_DBG("chstate 0x%x\n", channel->ch_ctx_host.chstate);
- IPA_MHI_DBG("brstmode 0x%x\n", channel->ch_ctx_host.brstmode);
- IPA_MHI_DBG("pollcfg 0x%x\n", channel->ch_ctx_host.pollcfg);
- IPA_MHI_DBG("chtype 0x%x\n", channel->ch_ctx_host.chtype);
- IPA_MHI_DBG("erindex 0x%x\n", channel->ch_ctx_host.erindex);
- IPA_MHI_DBG("rbase 0x%llx\n", channel->ch_ctx_host.rbase);
- IPA_MHI_DBG("rlen 0x%llx\n", channel->ch_ctx_host.rlen);
- IPA_MHI_DBG("rp 0x%llx\n", channel->ch_ctx_host.rp);
- IPA_MHI_DBG("wp 0x%llx\n", channel->ch_ctx_host.wp);
+ IPA_MHI_DBG_LOW("ch_id %d\n", channel->id);
+ IPA_MHI_DBG_LOW("chstate 0x%x\n", channel->ch_ctx_host.chstate);
+ IPA_MHI_DBG_LOW("brstmode 0x%x\n", channel->ch_ctx_host.brstmode);
+ IPA_MHI_DBG_LOW("pollcfg 0x%x\n", channel->ch_ctx_host.pollcfg);
+ IPA_MHI_DBG_LOW("chtype 0x%x\n", channel->ch_ctx_host.chtype);
+ IPA_MHI_DBG_LOW("erindex 0x%x\n", channel->ch_ctx_host.erindex);
+ IPA_MHI_DBG_LOW("rbase 0x%llx\n", channel->ch_ctx_host.rbase);
+ IPA_MHI_DBG_LOW("rlen 0x%llx\n", channel->ch_ctx_host.rlen);
+ IPA_MHI_DBG_LOW("rp 0x%llx\n", channel->ch_ctx_host.rp);
+ IPA_MHI_DBG_LOW("wp 0x%llx\n", channel->ch_ctx_host.wp);
}
static void ipa_mhi_dump_ev_ctx(struct ipa3_mhi_channel_ctx *channel)
{
- IPA_MHI_DBG("ch_id %d event id %d\n", channel->id,
+ IPA_MHI_DBG_LOW("ch_id %d event id %d\n", channel->id,
channel->ch_ctx_host.erindex);
- IPA_MHI_DBG("intmodc 0x%x\n", channel->ev_ctx_host.intmodc);
- IPA_MHI_DBG("intmodt 0x%x\n", channel->ev_ctx_host.intmodt);
- IPA_MHI_DBG("ertype 0x%x\n", channel->ev_ctx_host.ertype);
- IPA_MHI_DBG("msivec 0x%x\n", channel->ev_ctx_host.msivec);
- IPA_MHI_DBG("rbase 0x%llx\n", channel->ev_ctx_host.rbase);
- IPA_MHI_DBG("rlen 0x%llx\n", channel->ev_ctx_host.rlen);
- IPA_MHI_DBG("rp 0x%llx\n", channel->ev_ctx_host.rp);
- IPA_MHI_DBG("wp 0x%llx\n", channel->ev_ctx_host.wp);
+ IPA_MHI_DBG_LOW("intmodc 0x%x\n", channel->ev_ctx_host.intmodc);
+ IPA_MHI_DBG_LOW("intmodt 0x%x\n", channel->ev_ctx_host.intmodt);
+ IPA_MHI_DBG_LOW("ertype 0x%x\n", channel->ev_ctx_host.ertype);
+ IPA_MHI_DBG_LOW("msivec 0x%x\n", channel->ev_ctx_host.msivec);
+ IPA_MHI_DBG_LOW("rbase 0x%llx\n", channel->ev_ctx_host.rbase);
+ IPA_MHI_DBG_LOW("rlen 0x%llx\n", channel->ev_ctx_host.rlen);
+ IPA_MHI_DBG_LOW("rp 0x%llx\n", channel->ev_ctx_host.rp);
+ IPA_MHI_DBG_LOW("wp 0x%llx\n", channel->ev_ctx_host.wp);
}
static int ipa_mhi_read_ch_ctx(struct ipa3_mhi_channel_ctx *channel)
@@ -1671,9 +1699,10 @@ static int ipa_mhi_start_gsi_channel(struct ipa3_mhi_channel_ctx *channel,
channel->channel_context_addr +
offsetof(struct ipa3_mhi_ch_ctx, wp));
ch_scratch.mhi.assert_bit40 = ipa3_mhi_ctx->assert_bit40;
- ch_scratch.mhi.max_outstanding_tre = 0;
+ ch_scratch.mhi.max_outstanding_tre =
+ ep_cfg->ipa_if_tlv * ch_props.re_size;
ch_scratch.mhi.outstanding_threshold =
- 4 * GSI_CHAN_RE_SIZE_16B;
+ min(ep_cfg->ipa_if_tlv / 2, 8) * ch_props.re_size;
ch_scratch.mhi.oob_mod_threshold = 4;
if (channel->ch_ctx_host.brstmode == IPA_MHI_BURST_MODE_DEFAULT ||
channel->ch_ctx_host.brstmode == IPA_MHI_BURST_MODE_ENABLE) {
@@ -2234,7 +2263,7 @@ static int ipa3_mhi_suspend_ul_channels(void)
if (ipa3_mhi_ctx->ul_channels[i].state !=
IPA_HW_MHI_CHANNEL_STATE_RUN)
continue;
- IPA_MHI_DBG("suspending channel %d\n",
+ IPA_MHI_DBG_LOW("suspending channel %d\n",
ipa3_mhi_ctx->ul_channels[i].id);
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI)
@@ -2270,7 +2299,7 @@ static int ipa3_mhi_resume_ul_channels(bool LPTransitionRejected)
IPA_HW_MHI_CHANNEL_STATE_SUSPEND)
continue;
channel = &ipa3_mhi_ctx->ul_channels[i];
- IPA_MHI_DBG("resuming channel %d\n", channel->id);
+ IPA_MHI_DBG_LOW("resuming channel %d\n", channel->id);
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
if (channel->brstmode_enabled &&
@@ -2323,7 +2352,7 @@ static int ipa3_mhi_stop_event_update_ul_channels(void)
if (ipa3_mhi_ctx->ul_channels[i].state !=
IPA_HW_MHI_CHANNEL_STATE_SUSPEND)
continue;
- IPA_MHI_DBG("stop update event channel %d\n",
+ IPA_MHI_DBG_LOW("stop update event channel %d\n",
ipa3_mhi_ctx->ul_channels[i].id);
res = ipa3_uc_mhi_stop_event_update_channel(
ipa3_mhi_ctx->ul_channels[i].index);
@@ -2350,7 +2379,7 @@ static int ipa3_mhi_suspend_dl_channels(void)
if (ipa3_mhi_ctx->dl_channels[i].state !=
IPA_HW_MHI_CHANNEL_STATE_RUN)
continue;
- IPA_MHI_DBG("suspending channel %d\n",
+ IPA_MHI_DBG_LOW("suspending channel %d\n",
ipa3_mhi_ctx->dl_channels[i].id);
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI)
res = ipa3_mhi_suspend_gsi_channel(
@@ -2385,7 +2414,7 @@ static int ipa3_mhi_resume_dl_channels(bool LPTransitionRejected)
IPA_HW_MHI_CHANNEL_STATE_SUSPEND)
continue;
channel = &ipa3_mhi_ctx->dl_channels[i];
- IPA_MHI_DBG("resuming channel %d\n", channel->id);
+ IPA_MHI_DBG_LOW("resuming channel %d\n", channel->id);
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
if (channel->brstmode_enabled &&
@@ -2436,7 +2465,7 @@ static int ipa3_mhi_stop_event_update_dl_channels(void)
if (ipa3_mhi_ctx->dl_channels[i].state !=
IPA_HW_MHI_CHANNEL_STATE_SUSPEND)
continue;
- IPA_MHI_DBG("stop update event channel %d\n",
+ IPA_MHI_DBG_LOW("stop update event channel %d\n",
ipa3_mhi_ctx->dl_channels[i].id);
res = ipa3_uc_mhi_stop_event_update_channel(
ipa3_mhi_ctx->dl_channels[i].index);
@@ -2576,7 +2605,7 @@ static bool ipa3_mhi_has_open_aggr_frame(void)
int ipa_ep_idx;
aggr_state_active = ipahal_read_reg(IPA_STATE_AGGR_ACTIVE);
- IPA_MHI_DBG("IPA_STATE_AGGR_ACTIVE_OFST 0x%x\n", aggr_state_active);
+ IPA_MHI_DBG_LOW("IPA_STATE_AGGR_ACTIVE_OFST 0x%x\n", aggr_state_active);
for (i = 0; i < IPA_MHI_MAX_DL_CHANNELS; i++) {
channel = &ipa3_mhi_ctx->dl_channels[i];
@@ -2646,7 +2675,7 @@ int ipa3_mhi_suspend(bool force)
return res;
}
force_clear = true;
- IPA_MHI_DBG("force clear datapath enabled\n");
+ IPA_MHI_DBG_LOW("force clear datapath enabled\n");
empty = ipa3_mhi_wait_for_ul_empty_timeout(
IPA_MHI_CH_EMPTY_TIMEOUT_MSEC);
@@ -2675,7 +2704,7 @@ int ipa3_mhi_suspend(bool force)
BUG();
return res;
}
- IPA_MHI_DBG("force clear datapath disabled\n");
+ IPA_MHI_DBG_LOW("force clear datapath disabled\n");
ipa3_mhi_ctx->qmi_req_id++;
}
@@ -2700,14 +2729,14 @@ int ipa3_mhi_suspend(bool force)
*/
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
- IPA_MHI_DBG("release prod\n");
+ IPA_MHI_DBG_LOW("release prod\n");
res = ipa3_mhi_release_prod();
if (res) {
IPA_MHI_ERR("ipa3_mhi_release_prod failed %d\n", res);
goto fail_release_prod;
}
- IPA_MHI_DBG("wait for cons release\n");
+ IPA_MHI_DBG_LOW("wait for cons release\n");
res = ipa3_mhi_wait_for_cons_release();
if (res) {
IPA_MHI_ERR("ipa3_mhi_wait_for_cons_release failed %d\n", res);
@@ -2771,7 +2800,7 @@ fail_suspend_ul_channel:
IPA_MHI_ERR("failed to disable force clear\n");
BUG();
}
- IPA_MHI_DBG("force clear datapath disabled\n");
+ IPA_MHI_DBG_LOW("force clear datapath disabled\n");
ipa3_mhi_ctx->qmi_req_id++;
}
return res;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
index 4cd655aa8124..6444dcf3cfdc 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
@@ -356,7 +356,7 @@ static void ipa3_a5_svc_recv_msg(struct work_struct *work)
int rc;
do {
- IPAWANDBG("Notified about a Receive Event");
+ IPAWANDBG_LOW("Notified about a Receive Event");
rc = qmi_recv_msg(ipa3_svc_handle);
} while (rc == 0);
if (rc != -ENOMSG)
@@ -430,7 +430,7 @@ static int ipa3_check_qmi_response(int rc,
req_id, result, error);
return result;
}
- IPAWANDBG("Received %s successfully\n", resp_type);
+ IPAWANDBG_LOW("Received %s successfully\n", resp_type);
return 0;
}
@@ -762,7 +762,7 @@ static void ipa3_q6_clnt_recv_msg(struct work_struct *work)
int rc;
do {
- IPAWANDBG("Notified about a Receive Event");
+ IPAWANDBG_LOW("Notified about a Receive Event");
rc = qmi_recv_msg(ipa_q6_clnt);
} while (rc == 0);
if (rc != -ENOMSG)
@@ -774,7 +774,7 @@ static void ipa3_q6_clnt_notify(struct qmi_handle *handle,
{
switch (event) {
case QMI_RECV_MSG:
- IPAWANDBG("client qmi recv message called");
+ IPAWANDBG_LOW("client qmi recv message called");
if (!workqueues_stopped)
queue_delayed_work(ipa_clnt_resp_workqueue,
&ipa3_work_recv_msg_client, 0);
@@ -1154,7 +1154,7 @@ int ipa3_qmi_get_data_stats(struct ipa_get_data_stats_req_msg_v01 *req,
resp_desc.msg_id = QMI_IPA_GET_DATA_STATS_RESP_V01;
resp_desc.ei_array = ipa3_get_data_stats_resp_msg_data_v01_ei;
- IPAWANDBG("Sending QMI_IPA_GET_DATA_STATS_REQ_V01\n");
+ IPAWANDBG_LOW("Sending QMI_IPA_GET_DATA_STATS_REQ_V01\n");
rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, req,
sizeof(struct ipa_get_data_stats_req_msg_v01),
@@ -1162,7 +1162,7 @@ int ipa3_qmi_get_data_stats(struct ipa_get_data_stats_req_msg_v01 *req,
sizeof(struct ipa_get_data_stats_resp_msg_v01),
QMI_SEND_STATS_REQ_TIMEOUT_MS);
- IPAWANDBG("QMI_IPA_GET_DATA_STATS_RESP_V01 received\n");
+ IPAWANDBG_LOW("QMI_IPA_GET_DATA_STATS_RESP_V01 received\n");
return ipa3_check_qmi_response(rc,
QMI_IPA_GET_DATA_STATS_REQ_V01, resp->resp.result,
@@ -1183,7 +1183,7 @@ int ipa3_qmi_get_network_stats(struct ipa_get_apn_data_stats_req_msg_v01 *req,
resp_desc.msg_id = QMI_IPA_GET_APN_DATA_STATS_RESP_V01;
resp_desc.ei_array = ipa3_get_apn_data_stats_resp_msg_data_v01_ei;
- IPAWANDBG("Sending QMI_IPA_GET_APN_DATA_STATS_REQ_V01\n");
+ IPAWANDBG_LOW("Sending QMI_IPA_GET_APN_DATA_STATS_REQ_V01\n");
rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, req,
sizeof(struct ipa_get_apn_data_stats_req_msg_v01),
@@ -1191,7 +1191,7 @@ int ipa3_qmi_get_network_stats(struct ipa_get_apn_data_stats_req_msg_v01 *req,
sizeof(struct ipa_get_apn_data_stats_resp_msg_v01),
QMI_SEND_STATS_REQ_TIMEOUT_MS);
- IPAWANDBG("QMI_IPA_GET_APN_DATA_STATS_RESP_V01 received\n");
+ IPAWANDBG_LOW("QMI_IPA_GET_APN_DATA_STATS_RESP_V01 received\n");
return ipa3_check_qmi_response(rc,
QMI_IPA_GET_APN_DATA_STATS_REQ_V01, resp->resp.result,
@@ -1215,14 +1215,14 @@ int ipa3_qmi_set_data_quota(struct ipa_set_data_usage_quota_req_msg_v01 *req)
resp_desc.msg_id = QMI_IPA_SET_DATA_USAGE_QUOTA_RESP_V01;
resp_desc.ei_array = ipa3_set_data_usage_quota_resp_msg_data_v01_ei;
- IPAWANDBG("Sending QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01\n");
+ IPAWANDBG_LOW("Sending QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01\n");
rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, req,
sizeof(struct ipa_set_data_usage_quota_req_msg_v01),
&resp_desc, &resp, sizeof(resp),
QMI_SEND_STATS_REQ_TIMEOUT_MS);
- IPAWANDBG("QMI_IPA_SET_DATA_USAGE_QUOTA_RESP_V01 received\n");
+ IPAWANDBG_LOW("QMI_IPA_SET_DATA_USAGE_QUOTA_RESP_V01 received\n");
return ipa3_check_qmi_response(rc,
QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01, resp.resp.result,
@@ -1249,13 +1249,13 @@ int ipa3_qmi_stop_data_qouta(void)
resp_desc.msg_id = QMI_IPA_STOP_DATA_USAGE_QUOTA_RESP_V01;
resp_desc.ei_array = ipa3_stop_data_usage_quota_resp_msg_data_v01_ei;
- IPAWANDBG("Sending QMI_IPA_STOP_DATA_USAGE_QUOTA_REQ_V01\n");
+ IPAWANDBG_LOW("Sending QMI_IPA_STOP_DATA_USAGE_QUOTA_REQ_V01\n");
rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, &req, sizeof(req),
&resp_desc, &resp, sizeof(resp),
QMI_SEND_STATS_REQ_TIMEOUT_MS);
- IPAWANDBG("QMI_IPA_STOP_DATA_USAGE_QUOTA_RESP_V01 received\n");
+ IPAWANDBG_LOW("QMI_IPA_STOP_DATA_USAGE_QUOTA_RESP_V01 received\n");
return ipa3_check_qmi_response(rc,
QMI_IPA_STOP_DATA_USAGE_QUOTA_REQ_V01, resp.resp.result,
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
index 5f6722d3fbac..0f641204cc77 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
@@ -31,11 +31,39 @@
#define SUBSYS_MODEM "modem"
#define IPAWANDBG(fmt, args...) \
- pr_debug(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+ do { \
+ pr_debug(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ DEV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ DEV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+
+
+#define IPAWANDBG_LOW(fmt, args...) \
+ do { \
+ pr_debug(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ DEV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+
#define IPAWANERR(fmt, args...) \
- pr_err(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+ do { \
+ pr_err(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ DEV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ DEV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+
#define IPAWANINFO(fmt, args...) \
- pr_info(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+ do { \
+ pr_info(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ DEV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ DEV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
extern struct ipa3_qmi_context *ipa3_qmi_ctx;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 5ea39b732ee6..5574ef88398b 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -4439,6 +4439,21 @@ int ipa3_disable_apps_wan_cons_deaggr(uint32_t agg_size, uint32_t agg_count)
return res;
}
+static void *ipa3_get_ipc_logbuf(void)
+{
+ if (ipa3_ctx)
+ return ipa3_ctx->logbuf;
+
+ return NULL;
+}
+
+static void *ipa3_get_ipc_logbuf_low(void)
+{
+ if (ipa3_ctx)
+ return ipa3_ctx->logbuf_low;
+
+ return NULL;
+}
int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type,
struct ipa_api_controller *api_ctrl)
@@ -4576,6 +4591,8 @@ int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type,
api_ctrl->ipa_suspend_resource_sync = ipa3_suspend_resource_sync;
api_ctrl->ipa_set_required_perf_profile =
ipa3_set_required_perf_profile;
+ api_ctrl->ipa_get_ipc_logbuf = ipa3_get_ipc_logbuf;
+ api_ctrl->ipa_get_ipc_logbuf_low = ipa3_get_ipc_logbuf_low;
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
index 1fbe8865e2d1..6a282d70a189 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
@@ -10,7 +10,6 @@
* GNU General Public License for more details.
*/
-#include <linux/ipc_logging.h>
#include <linux/debugfs.h>
#include "ipahal.h"
#include "ipahal_i.h"
@@ -987,46 +986,12 @@ const char *ipahal_pkt_status_exception_str(
return ipahal_pkt_status_exception_to_str[exception];
}
-static int ipahal_ipc_logging_init(void)
-{
- ipahal_ctx->ipc_logbuf =
- ipc_log_context_create(IPAHAL_IPC_LOG_PAGES, "ipahal", 0);
- if (!ipahal_ctx->ipc_logbuf) {
- /* Cannot use the logging macros as no log buffers yet */
- pr_err("ipaghal: failed to create ipc_logbuf\n");
- return -ENOMEM;
- }
-
- ipahal_ctx->ipc_logbuf_low =
- ipc_log_context_create(IPAHAL_IPC_LOG_PAGES, "ipahal_low", 0);
- if (!ipahal_ctx->ipc_logbuf_low) {
- /* Cannot use the logging macros as no log buffers yet */
- pr_err("ipaghal: failed to create ipc_logbuf_low\n");
- ipc_log_context_destroy(ipahal_ctx->ipc_logbuf);
- return -ENOMEM;
- }
-
- return 0;
-}
-
#ifdef CONFIG_DEBUG_FS
static void ipahal_debugfs_init(void)
{
- const mode_t read_write_mode = S_IRUSR | S_IRGRP | S_IROTH |
- S_IWUSR | S_IWGRP;
-
ipahal_ctx->dent = debugfs_create_dir("ipahal", 0);
if (!ipahal_ctx->dent || IS_ERR(ipahal_ctx->dent)) {
IPAHAL_ERR("fail to create ipahal debugfs folder\n");
- return;
- }
-
- ipahal_ctx->dfile_enable_low_prio_ipc =
- debugfs_create_u32("enable_low_prio_log", read_write_mode,
- ipahal_ctx->dent, &ipahal_ctx->enable_low_prio_ipc);
- if (!ipahal_ctx->dfile_enable_low_prio_ipc ||
- IS_ERR(ipahal_ctx->dfile_enable_low_prio_ipc)) {
- IPAHAL_ERR("fail create enable_low_prio_log debugfs file\n");
goto fail;
}
@@ -1053,6 +1018,223 @@ static void ipahal_debugfs_init(void) {}
static void ipahal_debugfs_remove(void) {}
#endif /* CONFIG_DEBUG_FS */
+/*
+ * ipahal_cp_hdr_to_hw_buff_v3() - copy header to hardware buffer according to
+ * base address and offset given.
+ * @base: dma base address
+ * @offset: offset from base address where the data will be copied
+ * @hdr: the header to be copied
+ * @hdr_len: the length of the header
+ */
+static void ipahal_cp_hdr_to_hw_buff_v3(void *const base, u32 offset,
+ u8 *const hdr, u32 hdr_len)
+{
+ memcpy(base + offset, hdr, hdr_len);
+}
+
+/*
+ * ipahal_cp_proc_ctx_to_hw_buff_v3() - copy processing context to
+ * base address and offset given.
+ * @type: header processing context type (no processing context,
+ * IPA_HDR_PROC_ETHII_TO_ETHII etc.)
+ * @base: dma base address
+ * @offset: offset from base address where the data will be copied
+ * @hdr_len: the length of the header
+ * @is_hdr_proc_ctx: header is located in phys_base (true) or hdr_base_addr
+ * @phys_base: memory location in DDR
+ * @hdr_base_addr: base address in table
+ * @hdr_offset_entry: offset from hdr_base_addr in table
+ */
+static void ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type,
+ void *const base, u32 offset,
+ u32 hdr_len, bool is_hdr_proc_ctx,
+ dma_addr_t phys_base, u32 hdr_base_addr,
+ u32 hdr_offset_entry){
+ if (type == IPA_HDR_PROC_NONE) {
+ struct ipa_hw_hdr_proc_ctx_add_hdr_seq *ctx;
+
+ ctx = (struct ipa_hw_hdr_proc_ctx_add_hdr_seq *)
+ (base + offset);
+ ctx->hdr_add.tlv.type = IPA_PROC_CTX_TLV_TYPE_HDR_ADD;
+ ctx->hdr_add.tlv.length = 1;
+ ctx->hdr_add.tlv.value = hdr_len;
+ ctx->hdr_add.hdr_addr = is_hdr_proc_ctx ? phys_base :
+ hdr_base_addr + hdr_offset_entry;
+ IPAHAL_DBG("header address 0x%x\n",
+ ctx->hdr_add.hdr_addr);
+ ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END;
+ ctx->end.length = 0;
+ ctx->end.value = 0;
+ } else {
+ struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq *ctx;
+
+ ctx = (struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq *)
+ (base + offset);
+ ctx->hdr_add.tlv.type = IPA_PROC_CTX_TLV_TYPE_HDR_ADD;
+ ctx->hdr_add.tlv.length = 1;
+ ctx->hdr_add.tlv.value = hdr_len;
+ ctx->hdr_add.hdr_addr = is_hdr_proc_ctx ? phys_base :
+ hdr_base_addr + hdr_offset_entry;
+ IPAHAL_DBG("header address 0x%x\n",
+ ctx->hdr_add.hdr_addr);
+ ctx->cmd.type = IPA_PROC_CTX_TLV_TYPE_PROC_CMD;
+ ctx->cmd.length = 0;
+ switch (type) {
+ case IPA_HDR_PROC_ETHII_TO_ETHII:
+ ctx->cmd.value = IPA_HDR_UCP_ETHII_TO_ETHII;
+ break;
+ case IPA_HDR_PROC_ETHII_TO_802_3:
+ ctx->cmd.value = IPA_HDR_UCP_ETHII_TO_802_3;
+ break;
+ case IPA_HDR_PROC_802_3_TO_ETHII:
+ ctx->cmd.value = IPA_HDR_UCP_802_3_TO_ETHII;
+ break;
+ case IPA_HDR_PROC_802_3_TO_802_3:
+ ctx->cmd.value = IPA_HDR_UCP_802_3_TO_802_3;
+ break;
+ default:
+ IPAHAL_ERR("unknown ipa_hdr_proc_type %d", type);
+ BUG();
+ }
+ IPAHAL_DBG("command id %d\n", ctx->cmd.value);
+ ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END;
+ ctx->end.length = 0;
+ ctx->end.value = 0;
+ }
+}
+
+/*
+ * ipahal_get_proc_ctx_needed_len_v3() - calculates the needed length for
+ * addition of header processing context according to the type of processing
+ * context.
+ * @type: header processing context type (no processing context,
+ * IPA_HDR_PROC_ETHII_TO_ETHII etc.)
+ */
+static int ipahal_get_proc_ctx_needed_len_v3(enum ipa_hdr_proc_type type)
+{
+ return (type == IPA_HDR_PROC_NONE) ?
+ sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_seq) :
+ sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq);
+}
+
+/*
+ * struct ipahal_hdr_funcs - headers handling functions for specific IPA
+ * version
+ * @ipahal_cp_hdr_to_hw_buff - copy function for regular headers
+ */
+struct ipahal_hdr_funcs {
+ void (*ipahal_cp_hdr_to_hw_buff)(void *const base, u32 offset,
+ u8 *const hdr, u32 hdr_len);
+
+ void (*ipahal_cp_proc_ctx_to_hw_buff)(enum ipa_hdr_proc_type type,
+ void *const base, u32 offset, u32 hdr_len,
+ bool is_hdr_proc_ctx, dma_addr_t phys_base,
+ u32 hdr_base_addr, u32 hdr_offset_entry);
+
+ int (*ipahal_get_proc_ctx_needed_len)(enum ipa_hdr_proc_type type);
+};
+
+static struct ipahal_hdr_funcs hdr_funcs;
+
+static void ipahal_hdr_init(enum ipa_hw_type ipa_hw_type)
+{
+
+ IPAHAL_DBG("Entry - HW_TYPE=%d\n", ipa_hw_type);
+
+ /*
+ * once there are changes in HW and need to use different case, insert
+ * new case for the new h/w. put the default always for the latest HW
+ * and make sure all previous supported versions have their cases.
+ */
+ switch (ipa_hw_type) {
+ case IPA_HW_v3_0:
+ default:
+ hdr_funcs.ipahal_cp_hdr_to_hw_buff =
+ ipahal_cp_hdr_to_hw_buff_v3;
+ hdr_funcs.ipahal_cp_proc_ctx_to_hw_buff =
+ ipahal_cp_proc_ctx_to_hw_buff_v3;
+ hdr_funcs.ipahal_get_proc_ctx_needed_len =
+ ipahal_get_proc_ctx_needed_len_v3;
+ }
+ IPAHAL_DBG("Exit\n");
+}
+
+/*
+ * ipahal_cp_hdr_to_hw_buff() - copy header to hardware buffer according to
+ * base address and offset given.
+ * @base: dma base address
+ * @offset: offset from base address where the data will be copied
+ * @hdr: the header to be copied
+ * @hdr_len: the length of the header
+ */
+void ipahal_cp_hdr_to_hw_buff(void *base, u32 offset, u8 *const hdr,
+ u32 hdr_len)
+{
+ IPAHAL_DBG_LOW("Entry\n");
+ IPAHAL_DBG("base %p, offset %d, hdr %p, hdr_len %d\n", base,
+ offset, hdr, hdr_len);
+ BUG_ON(!base || !hdr_len || !hdr);
+
+ hdr_funcs.ipahal_cp_hdr_to_hw_buff(base, offset, hdr, hdr_len);
+
+ IPAHAL_DBG_LOW("Exit\n");
+}
+
+/*
+ * ipahal_cp_proc_ctx_to_hw_buff() - copy processing context to
+ * base address and offset given.
+ * @type: type of header processing context
+ * @base: dma base address
+ * @offset: offset from base address where the data will be copied
+ * @hdr_len: the length of the header
+ * @is_hdr_proc_ctx: header is located in phys_base (true) or hdr_base_addr
+ * @phys_base: memory location in DDR
+ * @hdr_base_addr: base address in table
+ * @hdr_offset_entry: offset from hdr_base_addr in table
+ */
+void ipahal_cp_proc_ctx_to_hw_buff(enum ipa_hdr_proc_type type,
+ void *const base, u32 offset, u32 hdr_len,
+ bool is_hdr_proc_ctx, dma_addr_t phys_base,
+ u32 hdr_base_addr, u32 hdr_offset_entry)
+{
+ IPAHAL_DBG_LOW("entry\n");
+ IPAHAL_DBG(
+ "type %d, base %p, offset %d, hdr_len %d, is_hdr_proc_ctx %d, hdr_base_addr %d, hdr_offset_entry %d\n"
+ , type, base, offset, hdr_len, is_hdr_proc_ctx,
+ hdr_base_addr, hdr_offset_entry);
+
+ BUG_ON(!base ||
+ !hdr_len ||
+ (!phys_base && !hdr_base_addr) ||
+ !hdr_base_addr);
+
+ hdr_funcs.ipahal_cp_proc_ctx_to_hw_buff(type, base, offset,
+ hdr_len, is_hdr_proc_ctx, phys_base,
+ hdr_base_addr, hdr_offset_entry);
+
+ IPAHAL_DBG_LOW("Exit\n");
+}
+
+/*
+ * ipahal_get_proc_ctx_needed_len() - calculates the needed length for
+ * addition of header processing context according to the type of processing
+ * context
+ * @type: header processing context type (no processing context,
+ * IPA_HDR_PROC_ETHII_TO_ETHII etc.)
+ */
+int ipahal_get_proc_ctx_needed_len(enum ipa_hdr_proc_type type)
+{
+ int res;
+
+ IPAHAL_DBG("entry\n");
+
+ res = hdr_funcs.ipahal_get_proc_ctx_needed_len(type);
+
+ IPAHAL_DBG("Exit\n");
+
+ return res;
+}
+
int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base)
{
int result;
@@ -1067,23 +1249,16 @@ int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base)
goto bail_err_exit;
}
- if (ipahal_ipc_logging_init()) {
- /* Cannot use the logging macros as no log buffers yet */
- pr_err("ipahal: failed to initialize ipc logging\n");
- result = -ENOMEM;
- goto bail_free_ctx;
- }
-
if (ipa_hw_type < IPA_HW_v3_0) {
IPAHAL_ERR("ipahal supported on IPAv3 and later only\n");
result = -EINVAL;
- goto bail_destroy_ipc;
+ goto bail_free_ctx;
}
if (!base) {
IPAHAL_ERR("invalid memory io mapping addr\n");
result = -EINVAL;
- goto bail_destroy_ipc;
+ goto bail_free_ctx;
}
ipahal_ctx->hw_type = ipa_hw_type;
@@ -1092,28 +1267,27 @@ int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base)
if (ipahal_reg_init(ipa_hw_type)) {
IPAHAL_ERR("failed to init ipahal reg\n");
result = -EFAULT;
- goto bail_destroy_ipc;
+ goto bail_free_ctx;
}
if (ipahal_imm_cmd_init(ipa_hw_type)) {
IPAHAL_ERR("failed to init ipahal imm cmd\n");
result = -EFAULT;
- goto bail_destroy_ipc;
+ goto bail_free_ctx;
}
if (ipahal_pkt_status_init(ipa_hw_type)) {
IPAHAL_ERR("failed to init ipahal pkt status\n");
result = -EFAULT;
- goto bail_destroy_ipc;
+ goto bail_free_ctx;
}
+ ipahal_hdr_init(ipa_hw_type);
+
ipahal_debugfs_init();
return 0;
-bail_destroy_ipc:
- ipc_log_context_destroy(ipahal_ctx->ipc_logbuf_low);
- ipc_log_context_destroy(ipahal_ctx->ipc_logbuf);
bail_free_ctx:
kfree(ipahal_ctx);
ipahal_ctx = NULL;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h
index 8591ff046624..1380b409d334 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h
@@ -597,6 +597,41 @@ void ipahal_pkt_status_parse(const void *unparsed_status,
const char *ipahal_pkt_status_exception_str(
enum ipahal_pkt_status_exception exception);
+/*
+ * ipahal_cp_hdr_to_hw_buff() - copy header to hardware buffer according to
+ * base address and offset given.
+ * @base: dma base address
+ * @offset: offset from base address where the data will be copied
+ * @hdr: the header to be copied
+ * @hdr_len: the length of the header
+ */
+void ipahal_cp_hdr_to_hw_buff(void *base, u32 offset, u8 *hdr, u32 hdr_len);
+
+/*
+ * ipahal_cp_proc_ctx_to_hw_buff() - copy processing context to
+ * base address and offset given.
+ * @type: type of header processing context
+ * @base: dma base address
+ * @offset: offset from base address where the data will be copied
+ * @hdr_len: the length of the header
+ * @is_hdr_proc_ctx: header is located in phys_base (true) or hdr_base_addr
+ * @phys_base: memory location in DDR
+ * @hdr_base_addr: base address in table
+ * @hdr_offset_entry: offset from hdr_base_addr in table
+ */
+void ipahal_cp_proc_ctx_to_hw_buff(enum ipa_hdr_proc_type type,
+ void *base, u32 offset, u32 hdr_len,
+ bool is_hdr_proc_ctx, dma_addr_t phys_base,
+ u32 hdr_base_addr, u32 hdr_offset_entry);
+
+/*
+ * ipahal_get_proc_ctx_needed_len() - calculates the needed length for addition
+ * of header processing context according to the type of processing context
+ * @type: header processing context type (no processing context,
+ * IPA_HDR_PROC_ETHII_TO_ETHII etc.)
+ */
+int ipahal_get_proc_ctx_needed_len(enum ipa_hdr_proc_type type);
+
int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base);
void ipahal_destroy(void);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
index 3c513a7d4dc1..6a22240e951b 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
@@ -13,44 +13,37 @@
#ifndef _IPAHAL_I_H_
#define _IPAHAL_I_H_
-#define IPAHAL_DRV_NAME "ipahal"
+#include <linux/ipa.h>
+#include "../../ipa_common_i.h"
-#define IPAHAL_IPC_LOG_PAGES 10
-#define IPAHAL_IPC_LOG(buf, fmt, args...) \
- ipc_log_string((buf), \
- IPAHAL_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+#define IPAHAL_DRV_NAME "ipahal"
#define IPAHAL_DBG(fmt, args...) \
do { \
- pr_debug(IPAHAL_DRV_NAME " %s:%d " fmt, \
- __func__, __LINE__, ## args); \
- if (likely(ipahal_ctx)) { \
- IPAHAL_IPC_LOG(ipahal_ctx->ipc_logbuf, fmt, ## args); \
- IPAHAL_IPC_LOG(ipahal_ctx->ipc_logbuf_low, \
- fmt, ## args); \
- } \
+ pr_debug(IPAHAL_DRV_NAME " %s:%d " fmt, __func__, __LINE__, \
+ ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPAHAL_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPAHAL_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define IPAHAL_DBG_LOW(fmt, args...) \
do { \
- pr_debug(IPAHAL_DRV_NAME " %s:%d " fmt, \
- __func__, __LINE__, ## args); \
- if (likely(ipahal_ctx) && \
- ipahal_ctx->enable_low_prio_ipc) { \
- IPAHAL_IPC_LOG(ipahal_ctx->ipc_logbuf_low, \
- fmt, ## args); \
- } \
+ pr_debug(IPAHAL_DRV_NAME " %s:%d " fmt, __func__, __LINE__, \
+ ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPAHAL_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define IPAHAL_ERR(fmt, args...) \
do { \
- pr_err(IPAHAL_DRV_NAME " %s:%d " fmt, \
- __func__, __LINE__, ## args); \
- if (likely(ipahal_ctx)) { \
- IPAHAL_IPC_LOG(ipahal_ctx->ipc_logbuf, fmt, ## args); \
- IPAHAL_IPC_LOG(ipahal_ctx->ipc_logbuf_low, \
- fmt, ## args); \
- } \
+ pr_err(IPAHAL_DRV_NAME " %s:%d " fmt, __func__, __LINE__, \
+ ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPAHAL_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPAHAL_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
/*
@@ -58,21 +51,13 @@
* @hw_type: IPA H/W type/version.
* @base: Base address to be used for accessing IPA memory. This is
* I/O memory mapped address.
- * @ipc_logbuf: IPC debug logs buffer
- * @ipc_logbuf_low: IPC Low priority debug logs buffer
- * @enable_low_prio_ipc: Flag telling to enable low priority logging
* Controlled by debugfs. default is off
* @dent: Debugfs folder dir entry
- * @dfile_enable_low_prio_ipc: Debugfs file for enable_low_prio_ipc
*/
struct ipahal_context {
enum ipa_hw_type hw_type;
void __iomem *base;
- void *ipc_logbuf;
- void *ipc_logbuf_low;
- u32 enable_low_prio_ipc;
struct dentry *dent;
- struct dentry *dfile_enable_low_prio_ipc;
};
extern struct ipahal_context *ipahal_ctx;
@@ -486,4 +471,75 @@ struct ipa_pkt_status_hw {
/* Size of H/W Packet Status */
#define IPA3_0_PKT_STATUS_SIZE 32
+/* Headers and processing context H/W structures and definitions */
+
+/* uCP command numbers */
+#define IPA_HDR_UCP_802_3_TO_802_3 6
+#define IPA_HDR_UCP_802_3_TO_ETHII 7
+#define IPA_HDR_UCP_ETHII_TO_802_3 8
+#define IPA_HDR_UCP_ETHII_TO_ETHII 9
+
+/* Processing context TLV type */
+#define IPA_PROC_CTX_TLV_TYPE_END 0
+#define IPA_PROC_CTX_TLV_TYPE_HDR_ADD 1
+#define IPA_PROC_CTX_TLV_TYPE_PROC_CMD 3
+
+/**
+ * struct ipa_hw_hdr_proc_ctx_tlv -
+ * HW structure of IPA processing context header - TLV part
+ * @type: 0 - end type
+ * 1 - header addition type
+ * 3 - processing command type
+ * @length: number of bytes after tlv
+ * for type:
+ * 0 - needs to be 0
+ * 1 - header addition length
+ * 3 - number of 32B including type and length.
+ * @value: specific value for type
+ * for type:
+ * 0 - needs to be 0
+ * 1 - header length
+ * 3 - command ID (see IPA_HDR_UCP_* definitions)
+ */
+struct ipa_hw_hdr_proc_ctx_tlv {
+ u32 type:8;
+ u32 length:8;
+ u32 value:16;
+};
+
+/**
+ * struct ipa_hw_hdr_proc_ctx_hdr_add -
+ * HW structure of IPA processing context - add header tlv
+ * @tlv: IPA processing context TLV
+ * @hdr_addr: processing context header address
+ */
+struct ipa_hw_hdr_proc_ctx_hdr_add {
+ struct ipa_hw_hdr_proc_ctx_tlv tlv;
+ u32 hdr_addr;
+};
+
+/**
+ * struct ipa_hw_hdr_proc_ctx_add_hdr_seq -
+ * IPA processing context header - add header sequence
+ * @hdr_add: add header command
+ * @end: tlv end command (cmd.type must be 0)
+ */
+struct ipa_hw_hdr_proc_ctx_add_hdr_seq {
+ struct ipa_hw_hdr_proc_ctx_hdr_add hdr_add;
+ struct ipa_hw_hdr_proc_ctx_tlv end;
+};
+
+/**
+ * struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq -
+ * IPA processing context header - process command sequence
+ * @hdr_add: add header command
+ * @cmd: tlv processing command (cmd.type must be 3)
+ * @end: tlv end command (cmd.type must be 0)
+ */
+struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq {
+ struct ipa_hw_hdr_proc_ctx_hdr_add hdr_add;
+ struct ipa_hw_hdr_proc_ctx_tlv cmd;
+ struct ipa_hw_hdr_proc_ctx_tlv end;
+};
+
#endif /* _IPAHAL_I_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
index 3451bf80a4fa..5694904ae429 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
@@ -10,7 +10,6 @@
* GNU General Public License for more details.
*/
-#include <linux/ipc_logging.h>
#include <linux/init.h>
#include <linux/ipa.h>
#include <linux/kernel.h>
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index 4b530ed8d010..eba5029509d8 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -1051,7 +1051,7 @@ static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev)
struct ipa_tx_meta meta;
if (skb->protocol != htons(ETH_P_MAP)) {
- IPAWANDBG
+ IPAWANDBG_LOW
("SW filtering out none QMAP packet received from %s",
current->comm);
return NETDEV_TX_OK;
@@ -1074,11 +1074,11 @@ static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev)
if (atomic_read(&wwan_ptr->outstanding_pkts) >=
wwan_ptr->outstanding_high) {
if (!qmap_check) {
- IPAWANDBG("pending(%d)/(%d)- stop(%d), qmap_chk(%d)\n",
+ IPAWANDBG_LOW("pending(%d)/(%d)- stop(%d)\n",
atomic_read(&wwan_ptr->outstanding_pkts),
wwan_ptr->outstanding_high,
- netif_queue_stopped(dev),
- qmap_check);
+ netif_queue_stopped(dev));
+ IPAWANDBG_LOW("qmap_chk(%d)\n", qmap_check);
netif_stop_queue(dev);
return NETDEV_TX_BUSY;
}
@@ -1165,7 +1165,7 @@ static void apps_ipa_tx_complete_notify(void *priv,
netif_queue_stopped(wwan_ptr->net) &&
atomic_read(&wwan_ptr->outstanding_pkts) <
(wwan_ptr->outstanding_low)) {
- IPAWANDBG("Outstanding low (%d) - waking up queue\n",
+ IPAWANDBG_LOW("Outstanding low (%d) - waking up queue\n",
wwan_ptr->outstanding_low);
netif_wake_queue(wwan_ptr->net);
}
@@ -1193,7 +1193,7 @@ static void apps_ipa_packet_receive_notify(void *priv,
int result;
unsigned int packet_len = skb->len;
- IPAWANDBG("Rx packet was received");
+ IPAWANDBG_LOW("Rx packet was received");
if (evt != IPA_RECEIVE) {
IPAWANERR("A none IPA_RECEIVE event in wan_ipa_receive\n");
return;
@@ -1733,10 +1733,10 @@ static void ipa3_q6_rm_notify_cb(void *user_data,
{
switch (event) {
case IPA_RM_RESOURCE_GRANTED:
- IPAWANDBG("%s: Q6_PROD GRANTED CB\n", __func__);
+ IPAWANDBG_LOW("%s: Q6_PROD GRANTED CB\n", __func__);
break;
case IPA_RM_RESOURCE_RELEASED:
- IPAWANDBG("%s: Q6_PROD RELEASED CB\n", __func__);
+ IPAWANDBG_LOW("%s: Q6_PROD RELEASED CB\n", __func__);
break;
default:
return;
@@ -1843,7 +1843,7 @@ static void ipa3_wake_tx_queue(struct work_struct *work)
*/
static void ipa3_rm_resource_granted(void *dev)
{
- IPAWANDBG("Resource Granted - starting queue\n");
+ IPAWANDBG_LOW("Resource Granted - starting queue\n");
schedule_work(&ipa3_tx_wakequeue_work);
}
@@ -2209,7 +2209,7 @@ static int rmnet_ipa_ap_suspend(struct device *dev)
struct net_device *netdev = IPA_NETDEV();
struct ipa3_wwan_private *wwan_ptr;
- IPAWANDBG("Enter...\n");
+ IPAWANDBG_LOW("Enter...\n");
if (netdev == NULL) {
IPAWANERR("netdev is NULL.\n");
return 0;
@@ -2231,7 +2231,7 @@ static int rmnet_ipa_ap_suspend(struct device *dev)
netif_tx_lock_bh(netdev);
ipa_rm_release_resource(IPA_RM_RESOURCE_WWAN_0_PROD);
netif_tx_unlock_bh(netdev);
- IPAWANDBG("Exit\n");
+ IPAWANDBG_LOW("Exit\n");
return 0;
}
@@ -2250,10 +2250,10 @@ static int rmnet_ipa_ap_resume(struct device *dev)
{
struct net_device *netdev = IPA_NETDEV();
- IPAWANDBG("Enter...\n");
+ IPAWANDBG_LOW("Enter...\n");
if (netdev)
netif_wake_queue(netdev);
- IPAWANDBG("Exit\n");
+ IPAWANDBG_LOW("Exit\n");
return 0;
}
@@ -2337,7 +2337,7 @@ static int ipa3_ssr_notifier_cb(struct notifier_block *this,
break;
}
- IPAWANDBG("Exit\n");
+ IPAWANDBG_LOW("Exit\n");
return NOTIFY_DONE;
}
@@ -2614,7 +2614,7 @@ int rmnet_ipa3_query_tethering_stats(struct wan_ioctl_query_tether_stats *data,
IPAWANERR("reset the pipe stats\n");
} else {
/* print tethered-client enum */
- IPAWANDBG("Tethered-client enum(%d)\n", data->ipa_client);
+ IPAWANDBG_LOW("Tethered-client enum(%d)\n", data->ipa_client);
}
rc = ipa3_qmi_get_data_stats(req, resp);
@@ -2632,16 +2632,17 @@ int rmnet_ipa3_query_tethering_stats(struct wan_ioctl_query_tether_stats *data,
if (resp->dl_dst_pipe_stats_list_valid) {
for (pipe_len = 0; pipe_len < resp->dl_dst_pipe_stats_list_len;
pipe_len++) {
- IPAWANDBG("Check entry(%d) dl_dst_pipe(%d)\n",
+ IPAWANDBG_LOW("Check entry(%d) dl_dst_pipe(%d)\n",
pipe_len, resp->dl_dst_pipe_stats_list
[pipe_len].pipe_index);
- IPAWANDBG("dl_p_v4(%lu)v6(%lu) dl_b_v4(%lu)v6(%lu)\n",
+ IPAWANDBG_LOW("dl_p_v4(%lu)v6(%lu)\n",
(unsigned long int) resp->
dl_dst_pipe_stats_list[pipe_len].
num_ipv4_packets,
(unsigned long int) resp->
dl_dst_pipe_stats_list[pipe_len].
- num_ipv6_packets,
+ num_ipv6_packets);
+ IPAWANDBG_LOW("dl_b_v4(%lu)v6(%lu)\n",
(unsigned long int) resp->
dl_dst_pipe_stats_list[pipe_len].
num_ipv4_bytes,
@@ -2671,7 +2672,7 @@ int rmnet_ipa3_query_tethering_stats(struct wan_ioctl_query_tether_stats *data,
}
}
}
- IPAWANDBG("v4_rx_p(%lu) v6_rx_p(%lu) v4_rx_b(%lu) v6_rx_b(%lu)\n",
+ IPAWANDBG_LOW("v4_rx_p(%lu) v6_rx_p(%lu) v4_rx_b(%lu) v6_rx_b(%lu)\n",
(unsigned long int) data->ipv4_rx_packets,
(unsigned long int) data->ipv6_rx_packets,
(unsigned long int) data->ipv4_rx_bytes,
@@ -2680,17 +2681,18 @@ int rmnet_ipa3_query_tethering_stats(struct wan_ioctl_query_tether_stats *data,
if (resp->ul_src_pipe_stats_list_valid) {
for (pipe_len = 0; pipe_len < resp->ul_src_pipe_stats_list_len;
pipe_len++) {
- IPAWANDBG("Check entry(%d) ul_dst_pipe(%d)\n",
+ IPAWANDBG_LOW("Check entry(%d) ul_dst_pipe(%d)\n",
pipe_len,
resp->ul_src_pipe_stats_list[pipe_len].
pipe_index);
- IPAWANDBG("ul_p_v4(%lu)v6(%lu)ul_b_v4(%lu)v6(%lu)\n",
+ IPAWANDBG_LOW("ul_p_v4(%lu)v6(%lu)\n",
(unsigned long int) resp->
ul_src_pipe_stats_list[pipe_len].
num_ipv4_packets,
(unsigned long int) resp->
ul_src_pipe_stats_list[pipe_len].
- num_ipv6_packets,
+ num_ipv6_packets);
+ IPAWANDBG_LOW("ul_b_v4(%lu)v6(%lu)\n",
(unsigned long int) resp->
ul_src_pipe_stats_list[pipe_len].
num_ipv4_bytes,
@@ -2720,7 +2722,7 @@ int rmnet_ipa3_query_tethering_stats(struct wan_ioctl_query_tether_stats *data,
}
}
}
- IPAWANDBG("tx_p_v4(%lu)v6(%lu)tx_b_v4(%lu) v6(%lu)\n",
+ IPAWANDBG_LOW("tx_p_v4(%lu)v6(%lu)tx_b_v4(%lu) v6(%lu)\n",
(unsigned long int) data->ipv4_tx_packets,
(unsigned long int) data->ipv6_tx_packets,
(unsigned long int) data->ipv4_tx_bytes,
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
index 608e6f23435e..80b07ab79163 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, 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
@@ -147,8 +147,7 @@ static long ipa3_wan_ioctl(struct file *filp,
break;
case WAN_IOC_POLL_TETHERING_STATS:
- IPAWANDBG("device %s got WAN_IOCTL_POLL_TETHERING_STATS :>>>\n",
- DRIVER_NAME);
+ IPAWANDBG_LOW("got WAN_IOCTL_POLL_TETHERING_STATS :>>>\n");
pyld_sz = sizeof(struct wan_ioctl_poll_tethering_stats);
param = kzalloc(pyld_sz, GFP_KERNEL);
if (!param) {
@@ -172,8 +171,7 @@ static long ipa3_wan_ioctl(struct file *filp,
break;
case WAN_IOC_SET_DATA_QUOTA:
- IPAWANDBG("device %s got WAN_IOCTL_SET_DATA_QUOTA :>>>\n",
- DRIVER_NAME);
+ IPAWANDBG_LOW("got WAN_IOCTL_SET_DATA_QUOTA :>>>\n");
pyld_sz = sizeof(struct wan_ioctl_set_data_quota);
param = kzalloc(pyld_sz, GFP_KERNEL);
if (!param) {
@@ -197,8 +195,7 @@ static long ipa3_wan_ioctl(struct file *filp,
break;
case WAN_IOC_SET_TETHER_CLIENT_PIPE:
- IPAWANDBG("device %s got WAN_IOC_SET_TETHER_CLIENT_PIPE :>>>\n",
- DRIVER_NAME);
+ IPAWANDBG_LOW("got WAN_IOC_SET_TETHER_CLIENT_PIPE :>>>\n");
pyld_sz = sizeof(struct wan_ioctl_set_tether_client_pipe);
param = kzalloc(pyld_sz, GFP_KERNEL);
if (!param) {
@@ -218,8 +215,7 @@ static long ipa3_wan_ioctl(struct file *filp,
break;
case WAN_IOC_QUERY_TETHER_STATS:
- IPAWANDBG("device %s got WAN_IOC_QUERY_TETHER_STATS :>>>\n",
- DRIVER_NAME);
+ IPAWANDBG_LOW("got WAN_IOC_QUERY_TETHER_STATS :>>>\n");
pyld_sz = sizeof(struct wan_ioctl_query_tether_stats);
param = kzalloc(pyld_sz, GFP_KERNEL);
if (!param) {
@@ -245,7 +241,7 @@ static long ipa3_wan_ioctl(struct file *filp,
break;
case WAN_IOC_RESET_TETHER_STATS:
- IPAWANDBG("device %s got WAN_IOC_RESET_TETHER_STATS :>>>\n",
+ IPAWANDBG_LOW("device %s got WAN_IOC_RESET_TETHER_STATS :>>>\n",
DRIVER_NAME);
pyld_sz = sizeof(struct wan_ioctl_reset_tether_stats);
param = kzalloc(pyld_sz, GFP_KERNEL);
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 9338e643c0ec..42c3c588678e 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -245,6 +245,7 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(restricted_charging),
POWER_SUPPLY_ATTR(current_capability),
POWER_SUPPLY_ATTR(typec_mode),
+ POWER_SUPPLY_ATTR(allow_hvdcp3),
/* Local extensions of type int64_t */
POWER_SUPPLY_ATTR(charge_counter_ext),
/* Properties of type `const char *' */
diff --git a/drivers/power/qcom/apm.c b/drivers/power/qcom/apm.c
index 9a36e5035ddd..ab5ee5a199e5 100644
--- a/drivers/power/qcom/apm.c
+++ b/drivers/power/qcom/apm.c
@@ -629,9 +629,15 @@ done:
#define MSM8953_APCC_APM_MODE 0x000002a8
#define MSM8953_APCC_APM_CTL_STS 0x000002b0
+/* 8953 constants */
+#define MSM8953_APM_SWITCH_TIMEOUT_US 500
+
+/* Register bit mask definitions */
+#define MSM8953_APM_CTL_STS_MASK 0x1f
+
static int msm8953_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
{
- int timeout = MSM_APM_SWITCH_TIMEOUT_US;
+ int timeout = MSM8953_APM_SWITCH_TIMEOUT_US;
u32 regval;
int ret = 0;
unsigned long flags;
@@ -648,7 +654,7 @@ static int msm8953_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
while (timeout > 0) {
regval = readl_relaxed(ctrl_dev->reg_base +
MSM8953_APCC_APM_CTL_STS);
- if ((regval & MSM_APM_CTL_STS_MASK) ==
+ if ((regval & MSM8953_APM_CTL_STS_MASK) ==
MSM8953_APM_MX_DONE_VAL)
break;
@@ -672,7 +678,7 @@ static int msm8953_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
static int msm8953_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)
{
- int timeout = MSM_APM_SWITCH_TIMEOUT_US;
+ int timeout = MSM8953_APM_SWITCH_TIMEOUT_US;
u32 regval;
int ret = 0;
unsigned long flags;
@@ -689,7 +695,7 @@ static int msm8953_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)
while (timeout > 0) {
regval = readl_relaxed(ctrl_dev->reg_base +
MSM8953_APCC_APM_CTL_STS);
- if ((regval & MSM_APM_CTL_STS_MASK) ==
+ if ((regval & MSM8953_APM_CTL_STS_MASK) ==
MSM8953_APM_APCC_DONE_VAL)
break;
diff --git a/drivers/power/qcom/msm-core.c b/drivers/power/qcom/msm-core.c
index dea9bc89ca5c..c817acf1bb26 100644
--- a/drivers/power/qcom/msm-core.c
+++ b/drivers/power/qcom/msm-core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -377,6 +377,7 @@ static int update_userspace_power(struct sched_params __user *argp)
struct cpu_activity_info *node;
struct cpu_static_info *sp, *clear_sp;
int cpumask, cluster, mpidr;
+ bool pdata_valid[NR_CPUS] = {0};
get_user(cpumask, &argp->cpumask);
get_user(cluster, &argp->cluster);
@@ -448,13 +449,19 @@ static int update_userspace_power(struct sched_params __user *argp)
}
cpu_stats[cpu].ptable = per_cpu(ptable, cpu);
repopulate_stats(cpu);
-
- blocking_notifier_call_chain(
- &msm_core_stats_notifier_list, cpu, NULL);
+ pdata_valid[cpu] = true;
}
}
spin_unlock(&update_lock);
+ for_each_possible_cpu(cpu) {
+ if (pdata_valid[cpu])
+ continue;
+
+ blocking_notifier_call_chain(
+ &msm_core_stats_notifier_list, cpu, NULL);
+ }
+
activate_power_table = true;
return 0;
diff --git a/drivers/power/qpnp-smbcharger.c b/drivers/power/qpnp-smbcharger.c
index 60dca083e093..f2077213eaef 100644
--- a/drivers/power/qpnp-smbcharger.c
+++ b/drivers/power/qpnp-smbcharger.c
@@ -139,6 +139,7 @@ struct smbchg_chip {
bool vbat_above_headroom;
bool force_aicl_rerun;
bool hvdcp3_supported;
+ bool allow_hvdcp3_detection;
bool restricted_charging;
bool skip_usb_suspend_for_fake_battery;
bool hvdcp_not_supported;
@@ -5104,6 +5105,30 @@ static int fake_insertion_removal(struct smbchg_chip *chip, bool insertion)
return 0;
}
+static void smbchg_handle_hvdcp3_disable(struct smbchg_chip *chip)
+{
+ enum power_supply_type usb_supply_type;
+ char *usb_type_name = "NULL";
+
+ if (chip->allow_hvdcp3_detection)
+ return;
+
+ chip->pulse_cnt = 0;
+
+ if (is_hvdcp_present(chip)) {
+ smbchg_change_usb_supply_type(chip,
+ POWER_SUPPLY_TYPE_USB_HVDCP);
+ } else if (is_usb_present(chip)) {
+ read_usb_type(chip, &usb_type_name, &usb_supply_type);
+ smbchg_change_usb_supply_type(chip, usb_supply_type);
+ if (usb_supply_type == POWER_SUPPLY_TYPE_USB_DCP)
+ schedule_delayed_work(&chip->hvdcp_det_work,
+ msecs_to_jiffies(HVDCP_NOTIFY_MS));
+ } else {
+ smbchg_change_usb_supply_type(chip, POWER_SUPPLY_TYPE_UNKNOWN);
+ }
+}
+
static int smbchg_prepare_for_pulsing(struct smbchg_chip *chip)
{
int rc = 0;
@@ -5158,6 +5183,8 @@ static int smbchg_prepare_for_pulsing(struct smbchg_chip *chip)
goto handle_removal;
}
+ set_usb_psy_dp_dm(chip, POWER_SUPPLY_DP_DM_DP0P6_DMF);
+
/* disable APSD */
pr_smb(PR_MISC, "Disabling APSD\n");
rc = smbchg_sec_masked_write(chip,
@@ -5181,7 +5208,6 @@ static int smbchg_prepare_for_pulsing(struct smbchg_chip *chip)
smbchg_sec_masked_write(chip, chip->usb_chgpth_base + USB_AICL_CFG,
AICL_EN_BIT, AICL_EN_BIT);
- set_usb_psy_dp_dm(chip, POWER_SUPPLY_DP_DM_DP0P6_DMF);
/*
* DCP will switch to HVDCP in this time by removing the short
* between DP DM
@@ -5319,6 +5345,9 @@ out:
pr_smb(PR_MISC, "HVDCP removed\n");
update_usb_status(chip, 0, 0);
}
+
+ smbchg_handle_hvdcp3_disable(chip);
+
return rc;
}
@@ -5503,6 +5532,8 @@ static int smbchg_unprepare_for_pulsing_lite(struct smbchg_chip *chip)
if (rc < 0)
pr_err("Couldn't retract HVDCP ICL vote rc=%d\n", rc);
+ smbchg_handle_hvdcp3_disable(chip);
+
return rc;
}
@@ -5717,6 +5748,7 @@ static enum power_supply_property smbchg_battery_properties[] = {
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED,
POWER_SUPPLY_PROP_RERUN_AICL,
POWER_SUPPLY_PROP_RESTRICTED_CHARGING,
+ POWER_SUPPLY_PROP_ALLOW_HVDCP3,
};
static int smbchg_battery_set_property(struct power_supply *psy,
@@ -5794,6 +5826,12 @@ static int smbchg_battery_set_property(struct power_supply *psy,
if (chip->typec_psy)
update_typec_otg_status(chip, val->intval, false);
break;
+ case POWER_SUPPLY_PROP_ALLOW_HVDCP3:
+ if (chip->allow_hvdcp3_detection != val->intval) {
+ chip->allow_hvdcp3_detection = !!val->intval;
+ power_supply_changed(&chip->batt_psy);
+ }
+ break;
default:
return -EINVAL;
}
@@ -5817,6 +5855,7 @@ static int smbchg_battery_is_writeable(struct power_supply *psy,
case POWER_SUPPLY_PROP_DP_DM:
case POWER_SUPPLY_PROP_RERUN_AICL:
case POWER_SUPPLY_PROP_RESTRICTED_CHARGING:
+ case POWER_SUPPLY_PROP_ALLOW_HVDCP3:
rc = 1;
break;
default:
@@ -5914,6 +5953,9 @@ static int smbchg_battery_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_INPUT_CURRENT_NOW:
val->intval = smbchg_get_iusb(chip);
break;
+ case POWER_SUPPLY_PROP_ALLOW_HVDCP3:
+ val->intval = chip->allow_hvdcp3_detection;
+ break;
default:
return -EINVAL;
}
@@ -6327,7 +6369,8 @@ static irqreturn_t usbin_uv_handler(int irq, void *_chip)
* set usb_psy's dp=f dm=f if this is a new insertion, i.e. it is
* not already src_detected and usbin_uv is seen falling
*/
- if (!(reg & USBIN_UV_BIT) && !(reg & USBIN_SRC_DET_BIT)) {
+ if (!(reg & USBIN_UV_BIT) && !(reg & USBIN_SRC_DET_BIT) &&
+ !chip->hvdcp_3_det_ignore_uv) {
pr_smb(PR_MISC, "setting usb psy dp=f dm=f\n");
power_supply_set_dp_dm(chip->usb_psy,
POWER_SUPPLY_DP_DM_DPF_DMF);
@@ -7826,6 +7869,7 @@ static int smbchg_check_chg_version(struct smbchg_chip *chip)
chip->schg_version = QPNP_SCHG;
break;
case PMI8950:
+ chip->wa_flags |= SMBCHG_RESTART_WA;
case PMI8937:
chip->wa_flags |= SMBCHG_BATT_OV_WA;
if (pmic_rev_id->rev4 < 2) /* PMI8950 1.0 */ {
@@ -8133,6 +8177,7 @@ static int smbchg_probe(struct spmi_device *spmi)
}
}
chip->psy_registered = true;
+ chip->allow_hvdcp3_detection = true;
if (chip->cfg_chg_led_support &&
chip->schg_version == QPNP_SCHG_LITE) {
diff --git a/drivers/regulator/cpr-regulator.c b/drivers/regulator/cpr-regulator.c
index 49941e368756..7afaacf4b4c2 100644
--- a/drivers/regulator/cpr-regulator.c
+++ b/drivers/regulator/cpr-regulator.c
@@ -5166,10 +5166,16 @@ static void tsens_threshold_notify(struct therm_threshold *tsens_cb_data)
break;
}
- rc = sensor_mgr_set_threshold(tsens_cb_data->sensor_id,
- tsens_cb_data->threshold);
- if (rc < 0)
- cpr_err(cpr_vreg, "Failed to set temp. threshold, rc=%d\n", rc);
+ if (tsens_cb_data->cur_state != tsens_cb_data->trip_triggered) {
+ rc = sensor_mgr_set_threshold(tsens_cb_data->sensor_id,
+ tsens_cb_data->threshold);
+ if (rc < 0)
+ cpr_err(cpr_vreg,
+ "Failed to set temp. threshold, rc=%d\n", rc);
+ else
+ tsens_cb_data->cur_state =
+ tsens_cb_data->trip_triggered;
+ }
}
static int cpr_check_tsens(struct cpr_regulator *cpr_vreg)
diff --git a/drivers/regulator/cpr3-regulator.c b/drivers/regulator/cpr3-regulator.c
index db82cfad77c2..be87975c45aa 100644
--- a/drivers/regulator/cpr3-regulator.c
+++ b/drivers/regulator/cpr3-regulator.c
@@ -5818,6 +5818,42 @@ static int cpr3_regulator_validate_controller(struct cpr3_controller *ctrl)
}
/**
+ * cpr3_panic_callback() - panic notification callback function. This function
+ * is invoked when a kernel panic occurs.
+ * @nfb: Notifier block pointer of CPR3 controller
+ * @event: Value passed unmodified to notifier function
+ * @data: Pointer passed unmodified to notifier function
+ *
+ * Return: NOTIFY_OK
+ */
+static int cpr3_panic_callback(struct notifier_block *nfb,
+ unsigned long event, void *data)
+{
+ struct cpr3_controller *ctrl = container_of(nfb,
+ struct cpr3_controller, panic_notifier);
+ struct cpr3_panic_regs_info *regs_info = ctrl->panic_regs_info;
+ struct cpr3_reg_info *reg;
+ void __iomem *virt_addr;
+ int i = 0;
+
+ for (i = 0; i < regs_info->reg_count; i++) {
+ reg = &(regs_info->regs[i]);
+ virt_addr = ioremap(reg->addr, 0x4);
+ reg->value = readl_relaxed(virt_addr);
+ iounmap(virt_addr);
+ pr_err("%s[0x%08x] = 0x%08x\n", reg->name, reg->addr,
+ reg->value);
+ }
+ /*
+ * Barrier to ensure that the information has been updated in the
+ * structure.
+ */
+ mb();
+
+ return NOTIFY_OK;
+}
+
+/**
* cpr3_regulator_register() - register the regulators for a CPR3 controller and
* perform CPR hardware initialization
* @pdev: Platform device pointer for the CPR3 controller
@@ -5968,6 +6004,13 @@ int cpr3_regulator_register(struct platform_device *pdev,
list_add(&ctrl->list, &cpr3_controller_list);
mutex_unlock(&cpr3_controller_list_mutex);
+ if (ctrl->panic_regs_info) {
+ /* Register panic notification call back */
+ ctrl->panic_notifier.notifier_call = cpr3_panic_callback;
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &ctrl->panic_notifier);
+ }
+
return 0;
free_regulators:
@@ -6021,5 +6064,9 @@ int cpr3_regulator_unregister(struct cpr3_controller *ctrl)
for (j = 0; j < ctrl->thread[i].vreg_count; j++)
regulator_unregister(ctrl->thread[i].vreg[j].rdev);
+ if (ctrl->panic_notifier.notifier_call)
+ atomic_notifier_chain_unregister(&panic_notifier_list,
+ &ctrl->panic_notifier);
+
return 0;
}
diff --git a/drivers/regulator/cpr3-regulator.h b/drivers/regulator/cpr3-regulator.h
index 0c4b6cb66805..d750b70519d1 100644
--- a/drivers/regulator/cpr3-regulator.h
+++ b/drivers/regulator/cpr3-regulator.h
@@ -494,6 +494,35 @@ struct cpr3_aging_sensor_info {
};
/**
+ * struct cpr3_reg_info - Register information data structure
+ * @name: Register name
+ * @addr: Register physical address
+ * @value: Register content
+ *
+ * This data structure is used to dump some critical register contents
+ * when the device crashes due to a kernel panic.
+ */
+struct cpr3_reg_info {
+ const char *name;
+ u32 addr;
+ u32 value;
+};
+
+/**
+ * struct cpr3_panic_regs_info - Data structure to dump critical register
+ * contents.
+ * @reg_count: Number of elements in the regs array
+ * @regs: Array of critical registers information
+ *
+ * This data structure is used to dump critical register contents when
+ * the device crashes due to a kernel panic.
+ */
+struct cpr3_panic_regs_info {
+ int reg_count;
+ struct cpr3_reg_info *regs;
+};
+
+/**
* struct cpr3_controller - CPR3 controller data structure
* @dev: Device pointer for the CPR3 controller device
* @name: Unique name for the CPR3 controller
@@ -662,6 +691,9 @@ struct cpr3_aging_sensor_info {
* VDD supply voltage to settle after being increased or
* decreased by step_volt microvolts which is used when
* SDELTA voltage margin adjustments are applied.
+ * @panic_regs_info: Array of panic registers information which provides the
+ * list of registers to dump when the device crashes.
+ * @panic_notifier: Notifier block registered to global panic notifier list.
*
* This structure contains both configuration and runtime state data. The
* elements cpr_allowed_sw, use_hw_closed_loop, aggr_corner, cpr_enabled,
@@ -755,6 +787,8 @@ struct cpr3_controller {
u32 temp_sensor_id_start;
u32 temp_sensor_id_end;
u32 voltage_settling_time;
+ struct cpr3_panic_regs_info *panic_regs_info;
+ struct notifier_block panic_notifier;
};
/* Used for rounding voltages to the closest physically available set point. */
diff --git a/drivers/regulator/cpr3-util.c b/drivers/regulator/cpr3-util.c
index 164579344c81..57631b14b5f6 100644
--- a/drivers/regulator/cpr3-util.c
+++ b/drivers/regulator/cpr3-util.c
@@ -1020,6 +1020,74 @@ static int cpr3_parse_irq_affinity(struct cpr3_controller *ctrl)
return 0;
}
+static int cpr3_panic_notifier_init(struct cpr3_controller *ctrl)
+{
+ struct device_node *node = ctrl->dev->of_node;
+ struct cpr3_panic_regs_info *panic_regs_info;
+ struct cpr3_reg_info *regs;
+ int i, reg_count, len, rc = 0;
+
+ if (!of_find_property(node, "qcom,cpr-panic-reg-addr-list", &len)) {
+ /* panic register address list not specified */
+ return rc;
+ }
+
+ reg_count = len / sizeof(u32);
+ if (!reg_count) {
+ cpr3_err(ctrl, "qcom,cpr-panic-reg-addr-list has invalid len = %d\n",
+ len);
+ return -EINVAL;
+ }
+
+ if (!of_find_property(node, "qcom,cpr-panic-reg-name-list", NULL)) {
+ cpr3_err(ctrl, "property qcom,cpr-panic-reg-name-list not specified\n");
+ return -EINVAL;
+ }
+
+ len = of_property_count_strings(node, "qcom,cpr-panic-reg-name-list");
+ if (reg_count != len) {
+ cpr3_err(ctrl, "qcom,cpr-panic-reg-name-list should have %d strings\n",
+ reg_count);
+ return -EINVAL;
+ }
+
+ panic_regs_info = devm_kzalloc(ctrl->dev, sizeof(*panic_regs_info),
+ GFP_KERNEL);
+ if (!panic_regs_info)
+ return -ENOMEM;
+
+ regs = devm_kcalloc(ctrl->dev, reg_count, sizeof(*regs), GFP_KERNEL);
+ if (!regs)
+ return -ENOMEM;
+
+ for (i = 0; i < reg_count; i++) {
+ rc = of_property_read_string_index(node,
+ "qcom,cpr-panic-reg-name-list", i,
+ &(regs[i].name));
+ if (rc) {
+ cpr3_err(ctrl, "error reading property qcom,cpr-panic-reg-name-list, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32_index(node,
+ "qcom,cpr-panic-reg-addr-list", i,
+ &(regs[i].addr));
+ if (rc) {
+ cpr3_err(ctrl, "error reading property qcom,cpr-panic-reg-addr-list, rc=%d\n",
+ rc);
+ return rc;
+ }
+ regs[i].value = 0xFFFFFFFF;
+ }
+
+ panic_regs_info->reg_count = reg_count;
+ panic_regs_info->regs = regs;
+ ctrl->panic_regs_info = panic_regs_info;
+
+ return rc;
+}
+
/**
* cpr3_parse_common_ctrl_data() - parse common CPR3 controller properties from
* device tree
@@ -1147,6 +1215,8 @@ int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl)
}
}
+ rc = cpr3_panic_notifier_init(ctrl);
+
return rc;
}
diff --git a/drivers/soc/qcom/bam_dmux.c b/drivers/soc/qcom/bam_dmux.c
index d23f9b9e1059..b3d5fee03ffe 100644
--- a/drivers/soc/qcom/bam_dmux.c
+++ b/drivers/soc/qcom/bam_dmux.c
@@ -1956,7 +1956,8 @@ static void ul_wakeup(void)
&ul_wakeup_ack_completion,
msecs_to_jiffies(UL_WAKEUP_TIMEOUT_MS));
wait_for_ack = 0;
- if (unlikely(ret == 0) && ssrestart_check()) {
+ if (unlikely(in_global_reset == 1)
+ || (unlikely(ret == 0) && ssrestart_check())) {
mutex_unlock(&wakeup_lock);
BAM_DMUX_LOG("%s timeout previous ack\n", __func__);
return;
@@ -1967,7 +1968,8 @@ static void ul_wakeup(void)
BAM_DMUX_LOG("%s waiting for wakeup ack\n", __func__);
ret = wait_for_completion_timeout(&ul_wakeup_ack_completion,
msecs_to_jiffies(UL_WAKEUP_TIMEOUT_MS));
- if (unlikely(ret == 0) && ssrestart_check()) {
+ if (unlikely(in_global_reset == 1)
+ || (unlikely(ret == 0) && ssrestart_check())) {
mutex_unlock(&wakeup_lock);
BAM_DMUX_LOG("%s timeout wakeup ack\n", __func__);
return;
@@ -1975,7 +1977,8 @@ static void ul_wakeup(void)
BAM_DMUX_LOG("%s waiting completion\n", __func__);
ret = wait_for_completion_timeout(&bam_connection_completion,
msecs_to_jiffies(UL_WAKEUP_TIMEOUT_MS));
- if (unlikely(ret == 0) && ssrestart_check()) {
+ if (unlikely(in_global_reset == 1)
+ || (unlikely(ret == 0) && ssrestart_check())) {
mutex_unlock(&wakeup_lock);
BAM_DMUX_LOG("%s timeout power on\n", __func__);
return;
@@ -2207,6 +2210,9 @@ static int restart_notifier_cb(struct notifier_block *this,
if (code == SUBSYS_BEFORE_SHUTDOWN) {
BAM_DMUX_LOG("%s: begin\n", __func__);
in_global_reset = 1;
+ /* wakeup ul_wakeup() thread*/
+ complete_all(&ul_wakeup_ack_completion);
+ complete_all(&bam_connection_completion);
/* sync to ensure the driver sees SSR */
synchronize_srcu(&bam_dmux_srcu);
BAM_DMUX_LOG("%s: ssr signaling complete\n", __func__);
diff --git a/drivers/soc/qcom/pil-q6v5.c b/drivers/soc/qcom/pil-q6v5.c
index eb8e6d510d1e..0055c018c195 100644
--- a/drivers/soc/qcom/pil-q6v5.c
+++ b/drivers/soc/qcom/pil-q6v5.c
@@ -113,7 +113,7 @@ int pil_q6v5_make_proxy_votes(struct pil_desc *pil)
goto err_qdss_vote;
}
- ret = regulator_set_voltage(drv->vreg_cx, uv, uv);
+ ret = regulator_set_voltage(drv->vreg_cx, uv, INT_MAX);
if (ret) {
dev_err(pil->dev, "Failed to request vdd_cx voltage.\n");
goto err_cx_voltage;
diff --git a/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c b/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c
index 653f665b6e5d..14e46b38c6df 100644
--- a/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c
+++ b/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c
@@ -210,6 +210,25 @@ bool apr_tal_notify_rx_intent_req(void *handle, const void *priv,
return false;
}
+static void apr_tal_notify_remote_rx_intent(void *handle, const void *priv,
+ size_t size)
+{
+ struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv;
+
+ if (!apr_ch) {
+ pr_err("%s: Invalid apr_ch\n", __func__);
+ return;
+ }
+ /*
+ * This is to make sure that the far end has queued at least one intent
+ * before we attmpt any IPC. A simple bool flag is used here instead of
+ * a counter, as the far end is required to guarantee intent
+ * availability for all use cases once the channel is fully opened.
+ */
+ pr_debug("%s: remote queued an intent\n", __func__);
+ apr_ch->if_remote_intent_ready = true;
+}
+
void apr_tal_notify_state(void *handle, const void *priv, unsigned event)
{
struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv;
@@ -295,6 +314,7 @@ struct apr_svc_ch_dev *apr_tal_open(uint32_t clnt, uint32_t dest, uint32_t dl,
open_cfg.notify_tx_done = apr_tal_notify_tx_done;
open_cfg.notify_state = apr_tal_notify_state;
open_cfg.notify_rx_intent_req = apr_tal_notify_rx_intent_req;
+ open_cfg.notify_remote_rx_intent = apr_tal_notify_remote_rx_intent;
open_cfg.priv = apr_ch;
/*
* The transport name "smd_trans" is required if far end is using SMD.
@@ -321,6 +341,15 @@ struct apr_svc_ch_dev *apr_tal_open(uint32_t clnt, uint32_t dest, uint32_t dl,
goto close_link;
}
+ /*
+ * Remote intent is not required for GLINK <--> SMD IPC, so this is
+ * designed not to fail the open call.
+ */
+ rc = wait_event_timeout(apr_ch->wait,
+ apr_ch->if_remote_intent_ready, 5 * HZ);
+ if (rc == 0)
+ pr_err("%s: TIMEOUT for remote intent readiness\n", __func__);
+
rc = apr_tal_rx_intents_config(apr_ch, APR_DEFAULT_NUM_OF_INTENTS,
APR_MAX_BUF);
if (rc) {
@@ -356,6 +385,7 @@ int apr_tal_close(struct apr_svc_ch_dev *apr_ch)
apr_ch->handle = NULL;
apr_ch->func = NULL;
apr_ch->priv = NULL;
+ apr_ch->if_remote_intent_ready = false;
mutex_unlock(&apr_ch->m_lock);
exit:
return rc;
diff --git a/drivers/soc/qcom/subsystem_restart.c b/drivers/soc/qcom/subsystem_restart.c
index d66fab897ab3..19930c37e5a6 100644
--- a/drivers/soc/qcom/subsystem_restart.c
+++ b/drivers/soc/qcom/subsystem_restart.c
@@ -70,17 +70,20 @@ enum p_subsys_state {
/**
* enum subsys_state - state of a subsystem (public)
+ * @SUBSYS_OFFLINING: subsystem is offlining
* @SUBSYS_OFFLINE: subsystem is offline
* @SUBSYS_ONLINE: subsystem is online
*
* The 'public' side of the subsytem state, exposed to userspace.
*/
enum subsys_state {
+ SUBSYS_OFFLINING,
SUBSYS_OFFLINE,
SUBSYS_ONLINE,
};
static const char * const subsys_states[] = {
+ [SUBSYS_OFFLINING] = "OFFLINING",
[SUBSYS_OFFLINE] = "OFFLINE",
[SUBSYS_ONLINE] = "ONLINE",
};
@@ -728,6 +731,7 @@ static void subsys_stop(struct subsys_device *subsys)
if (!of_property_read_bool(subsys->desc->dev->of_node,
"qcom,pil-force-shutdown")) {
+ subsys_set_state(subsys, SUBSYS_OFFLINING);
subsys->desc->sysmon_shutdown_ret =
sysmon_send_shutdown(subsys->desc);
if (subsys->desc->sysmon_shutdown_ret)
diff --git a/drivers/soundwire/soundwire.c b/drivers/soundwire/soundwire.c
index 23642fe38ef3..2ca4faedd4b3 100644
--- a/drivers/soundwire/soundwire.c
+++ b/drivers/soundwire/soundwire.c
@@ -240,6 +240,43 @@ void swr_port_response(struct swr_master *mstr, u8 tid)
EXPORT_SYMBOL(swr_port_response);
/**
+ * swr_slvdev_datapath_control - Enables/Disables soundwire slave device
+ * data path
+ * @dev: pointer to soundwire slave device
+ * @dev_num: device number of the soundwire slave device
+ *
+ * Returns error code for failure and 0 for success
+ */
+int swr_slvdev_datapath_control(struct swr_device *dev, u8 dev_num,
+ bool enable)
+{
+ struct swr_master *master;
+
+ if (!dev)
+ return -ENODEV;
+
+ master = dev->master;
+ if (!master)
+ return -EINVAL;
+
+ if (dev->group_id) {
+ /* Broadcast */
+ if (master->gr_sid != dev_num) {
+ if (!master->gr_sid)
+ master->gr_sid = dev_num;
+ else
+ return 0;
+ }
+ }
+
+ if (master->slvdev_datapath_control)
+ master->slvdev_datapath_control(master, enable);
+
+ return 0;
+}
+EXPORT_SYMBOL(swr_slvdev_datapath_control);
+
+/**
* swr_connect_port - enable soundwire slave port(s)
* @dev: pointer to soundwire slave device
* @port_id: logical port id(s) of soundwire slave device
diff --git a/drivers/soundwire/swr-wcd-ctrl.c b/drivers/soundwire/swr-wcd-ctrl.c
index b18ffca8d735..83fb7dc6fae2 100644
--- a/drivers/soundwire/swr-wcd-ctrl.c
+++ b/drivers/soundwire/swr-wcd-ctrl.c
@@ -601,6 +601,62 @@ static struct swr_port_info *swrm_get_port(struct swr_master *master,
return port;
}
+static void swrm_slvdev_datapath_control(struct swr_master *master,
+ bool enable)
+{
+ u8 bank;
+ u32 value, n_col;
+ struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
+ int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK |
+ SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK |
+ SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK);
+ int col_mask = SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK;
+ u8 active_bank;
+
+ bank = get_inactive_bank_num(swrm);
+
+ dev_dbg(swrm->dev, "%s: enable: %d, slvdev_dp_enable_cnt: %d\n",
+ __func__, enable, swrm->slvdev_dp_enable_cnt);
+
+ if (enable) {
+ swrm->slvdev_dp_enable_cnt++;
+ active_bank = bank ? 0 : 1;
+ value = swrm->read(swrm->handle,
+ SWRM_MCP_FRAME_CTRL_BANK_ADDR(active_bank));
+ if (((value & col_mask) >>
+ SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) ==
+ SWR_MAX_COL)
+ return;
+
+ /* set Row = 48 and col = 16 */
+ n_col = SWR_MAX_COL;
+ } else {
+ /*
+ * Do not change to 48x2 if number of channels configured
+ * as stereo and if disable datapath is called for the
+ * first slave device
+ */
+ swrm->slvdev_dp_enable_cnt--;
+ if (swrm->slvdev_dp_enable_cnt > 0)
+ return;
+
+ /* set Row = 48 and col = 2 */
+ n_col = SWR_MIN_COL;
+ }
+
+ value = swrm->read(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank));
+ value &= (~mask);
+ value |= ((0 << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
+ (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
+ (0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
+ swrm->write(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
+
+ dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__,
+ SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
+
+ enable_bank_switch(swrm, bank, SWR_MAX_ROW, n_col);
+}
+
static void swrm_apply_port_config(struct swr_master *master)
{
u32 value;
@@ -615,10 +671,6 @@ static void swrm_apply_port_config(struct swr_master *master)
u32 val[SWRM_MAX_PORT_REG];
int len = 0;
- int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK |
- SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK |
- SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK);
-
if (!swrm) {
pr_err("%s: Invalid handle to swr controller\n",
__func__);
@@ -629,15 +681,6 @@ static void swrm_apply_port_config(struct swr_master *master)
dev_dbg(swrm->dev, "%s: enter bank: %d master_ports: %d\n",
__func__, bank, master->num_port);
- /* set Row = 48 and col = 16 */
- value = swrm->read(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank));
- value &= (~mask);
- value |= ((0 << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
- (7 << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
- (0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
- swrm->write(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
- dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__,
- SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00,
SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank));
@@ -703,7 +746,6 @@ static void swrm_apply_port_config(struct swr_master *master)
}
}
swrm->bulk_write(swrm->handle, reg, val, len);
- enable_bank_switch(swrm, bank, SWR_MAX_ROW, SWR_MAX_COL);
}
static int swrm_connect_port(struct swr_master *master,
@@ -1057,6 +1099,7 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm)
u32 value[SWRM_MAX_INIT_REG];
int len = 0;
+ swrm->slvdev_dp_enable_cnt = 0;
/* Clear Rows and Cols */
val = ((row_ctrl << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
(col_ctrl << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
@@ -1174,6 +1217,7 @@ static int swrm_probe(struct platform_device *pdev)
swrm->master.get_logical_dev_num = swrm_get_logical_dev_num;
swrm->master.connect_port = swrm_connect_port;
swrm->master.disconnect_port = swrm_disconnect_port;
+ swrm->master.slvdev_datapath_control = swrm_slvdev_datapath_control;
swrm->master.dev.parent = &pdev->dev;
swrm->master.dev.of_node = pdev->dev.of_node;
swrm->master.num_port = 0;
diff --git a/drivers/soundwire/swr-wcd-ctrl.h b/drivers/soundwire/swr-wcd-ctrl.h
index b5d477523315..a9248425deea 100644
--- a/drivers/soundwire/swr-wcd-ctrl.h
+++ b/drivers/soundwire/swr-wcd-ctrl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -96,6 +96,7 @@ struct swr_mstr_ctrl {
struct platform_device *pdev;
int num_rx_chs;
u8 num_cfg_devs;
+ u8 slvdev_dp_enable_cnt;
};
#endif /* _SWR_WCD_CTRL_H */
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index b21b6888b169..9244af11e0c9 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -159,7 +159,6 @@ static bool ocr_nodes_called;
static bool ocr_probed;
static bool ocr_reg_init_defer;
static bool hotplug_enabled;
-static bool interrupt_mode_enable;
static bool msm_thermal_probed;
static bool gfx_crit_phase_ctrl_enabled;
static bool gfx_warm_phase_ctrl_enabled;
@@ -1806,14 +1805,14 @@ static int vdd_restriction_apply_voltage(struct rail *r, int level)
/* level = -1: disable, level = 0,1,2..n: enable */
if (level == -1) {
ret = regulator_set_voltage(r->reg, r->min_level,
- r->levels[r->num_levels - 1]);
+ INT_MAX);
if (!ret)
r->curr_level = -1;
pr_debug("Requested min level for %s. curr level: %d\n",
r->name, r->curr_level);
} else if (level >= 0 && level < (r->num_levels)) {
ret = regulator_set_voltage(r->reg, r->levels[level],
- r->levels[r->num_levels - 1]);
+ INT_MAX);
if (!ret)
r->curr_level = level;
pr_debug("Requesting level %d for %s. curr level: %d\n",
@@ -2695,8 +2694,12 @@ static void vdd_mx_notify(struct therm_threshold *trig_thresh)
pr_err("Failed to remove vdd mx restriction\n");
}
mutex_unlock(&vdd_mx_mutex);
- sensor_mgr_set_threshold(trig_thresh->sensor_id,
+
+ if (trig_thresh->cur_state != trig_thresh->trip_triggered) {
+ sensor_mgr_set_threshold(trig_thresh->sensor_id,
trig_thresh->threshold);
+ trig_thresh->cur_state = trig_thresh->trip_triggered;
+ }
}
static void msm_thermal_bite(int zone_id, long temp)
@@ -4069,8 +4072,11 @@ static void cx_phase_ctrl_notify(struct therm_threshold *trig_thresh)
cx_phase_unlock_exit:
mutex_unlock(&cx_mutex);
cx_phase_ctrl_exit:
- sensor_mgr_set_threshold(trig_thresh->sensor_id,
+ if (trig_thresh->cur_state != trig_thresh->trip_triggered) {
+ sensor_mgr_set_threshold(trig_thresh->sensor_id,
trig_thresh->threshold);
+ trig_thresh->cur_state = trig_thresh->trip_triggered;
+ }
return;
}
@@ -4198,8 +4204,11 @@ static void vdd_restriction_notify(struct therm_threshold *trig_thresh)
unlock_and_exit:
mutex_unlock(&vdd_rstr_mutex);
set_and_exit:
- sensor_mgr_set_threshold(trig_thresh->sensor_id,
+ if (trig_thresh->cur_state != trig_thresh->trip_triggered) {
+ sensor_mgr_set_threshold(trig_thresh->sensor_id,
trig_thresh->threshold);
+ trig_thresh->cur_state = trig_thresh->trip_triggered;
+ }
return;
}
@@ -4247,8 +4256,11 @@ static void ocr_notify(struct therm_threshold *trig_thresh)
unlock_and_exit:
mutex_unlock(&ocr_mutex);
set_and_exit:
- sensor_mgr_set_threshold(trig_thresh->sensor_id,
- trig_thresh->threshold);
+ if (trig_thresh->cur_state != trig_thresh->trip_triggered) {
+ sensor_mgr_set_threshold(trig_thresh->sensor_id,
+ trig_thresh->threshold);
+ trig_thresh->cur_state = trig_thresh->trip_triggered;
+ }
return;
}
@@ -4483,6 +4495,7 @@ int sensor_mgr_init_threshold(struct threshold_info *thresh_inp,
thresh_ptr[i].notify = callback;
thresh_ptr[i].trip_triggered = -1;
thresh_ptr[i].parent = thresh_inp;
+ thresh_ptr[i].cur_state = -1;
thresh_ptr[i].threshold[0].temp =
high_temp * tsens_scaling_factor;
thresh_ptr[i].threshold[0].trip =
@@ -4503,6 +4516,7 @@ int sensor_mgr_init_threshold(struct threshold_info *thresh_inp,
thresh_ptr->notify = callback;
thresh_ptr->trip_triggered = -1;
thresh_ptr->parent = thresh_inp;
+ thresh_ptr->cur_state = -1;
thresh_ptr->threshold[0].temp = high_temp * tsens_scaling_factor;
thresh_ptr->threshold[0].trip =
THERMAL_TRIP_CONFIGURABLE_HI;
@@ -4679,10 +4693,9 @@ static void __ref disable_msm_thermal(void)
static void interrupt_mode_init(void)
{
- if (!msm_thermal_probed) {
- interrupt_mode_enable = true;
+ if (!msm_thermal_probed)
return;
- }
+
if (polling_enabled) {
polling_enabled = 0;
create_sensor_zone_id_map();
@@ -5784,6 +5797,13 @@ static int probe_vdd_mx(struct device_node *node,
if (ret)
goto read_node_done;
+ /*
+ * Monitor only this sensor if defined, otherwise monitor all tsens
+ */
+ key = "qcom,mx-restriction-sensor_id";
+ if (of_property_read_u32(node, key, &data->vdd_mx_sensor_id))
+ data->vdd_mx_sensor_id = MONITOR_ALL_TSENS;
+
vdd_mx = devm_regulator_get(&pdev->dev, "vdd-mx");
if (IS_ERR_OR_NULL(vdd_mx)) {
ret = PTR_ERR(vdd_mx);
@@ -5810,7 +5830,7 @@ static int probe_vdd_mx(struct device_node *node,
}
ret = sensor_mgr_init_threshold(&thresh[MSM_VDD_MX_RESTRICTION],
- MONITOR_ALL_TSENS,
+ data->vdd_mx_sensor_id,
data->vdd_mx_temp_degC + data->vdd_mx_temp_hyst_degC,
data->vdd_mx_temp_degC, vdd_mx_notify);
@@ -6749,6 +6769,9 @@ static void thermal_mx_config_read(struct seq_file *m, void *data)
if (vdd_cx)
seq_printf(m, "cx retention value:%d\n",
msm_thermal_info.vdd_cx_min);
+ if (msm_thermal_info.vdd_mx_sensor_id != MONITOR_ALL_TSENS)
+ seq_printf(m, "tsens sensor:tsens_tz_sensor%d\n",
+ msm_thermal_info.vdd_mx_sensor_id);
}
}
@@ -7094,11 +7117,6 @@ static int msm_thermal_dev_probe(struct platform_device *pdev)
ret = msm_thermal_init(&data);
msm_thermal_probed = true;
- if (interrupt_mode_enable) {
- interrupt_mode_init();
- interrupt_mode_enable = false;
- }
-
return ret;
fail:
if (ret)
@@ -7234,7 +7252,6 @@ int __init msm_thermal_late_init(void)
}
}
msm_thermal_add_mx_nodes();
- interrupt_mode_init();
create_cpu_topology_sysfs();
create_thermal_debugfs();
msm_thermal_add_bucket_info_nodes();
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 27508d2b5bfe..3690303f33cc 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1553,6 +1553,8 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
atomic_inc(&urb->use_count);
atomic_inc(&urb->dev->urbnum);
usbmon_urb_submit(&hcd->self, urb);
+ if (hcd->driver->log_urb)
+ hcd->driver->log_urb(urb, "S", urb->status);
/* NOTE requirements on root-hub callers (usbfs and the hub
* driver, for now): URBs' urb->transfer_buffer must be
@@ -1575,6 +1577,8 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
if (unlikely(status)) {
usbmon_urb_submit_error(&hcd->self, urb, status);
+ if (hcd->driver->log_urb)
+ hcd->driver->log_urb(urb, "E", status);
urb->hcpriv = NULL;
INIT_LIST_HEAD(&urb->urb_list);
atomic_dec(&urb->use_count);
@@ -1663,6 +1667,8 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
unmap_urb_for_dma(hcd, urb);
usbmon_urb_complete(&hcd->self, urb, status);
+ if (hcd->driver->log_urb)
+ hcd->driver->log_urb(urb, "C", status);
usb_anchor_suspend_wakeups(anchor);
usb_unanchor_urb(urb);
if (likely(status == 0))
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 2222899c4b69..3c26acd61b5c 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4327,7 +4327,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
bool did_new_scheme = false;
- if (use_new_scheme(udev, retry_counter)) {
+ if (use_new_scheme(udev, retry_counter) &&
+ !((hcd->driver->flags & HCD_RT_OLD_ENUM) &&
+ !hdev->parent)) {
struct usb_device_descriptor *buf;
int r = 0;
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 206664ca6e2c..47f6327d3eed 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -67,6 +67,10 @@ static int cpu_to_affin;
module_param(cpu_to_affin, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(cpu_to_affin, "affin usb irq to this cpu");
+static bool disable_host_mode;
+module_param(disable_host_mode, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(disable_host_mode, "To stop HOST mode detection");
+
static int override_phy_init;
module_param(override_phy_init, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(override_phy_init, "Override HSPHY Init Seq");
@@ -657,11 +661,34 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
int ret = 0, size;
bool superspeed;
+ /*
+ * We must obtain the lock of the dwc3 core driver,
+ * including disabling interrupts, so we will be sure
+ * that we are the only ones that configure the HW device
+ * core and ensure that we queuing the request will finish
+ * as soon as possible so we will release back the lock.
+ */
+ spin_lock_irqsave(&dwc->lock, flags);
+ if (!dep->endpoint.desc) {
+ dev_err(mdwc->dev,
+ "%s: trying to queue request %p to disabled ep %s\n",
+ __func__, request, ep->name);
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -EPERM;
+ }
+
+ if (!request) {
+ dev_err(mdwc->dev, "%s: request is NULL\n", __func__);
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -EINVAL;
+ }
+
if (!(request->udc_priv & MSM_SPS_MODE)) {
/* Not SPS mode, call original queue */
dev_vdbg(mdwc->dev, "%s: not sps mode, use regular queue\n",
__func__);
+ spin_unlock_irqrestore(&dwc->lock, flags);
return (mdwc->original_ep_ops[dep->number])->queue(ep,
request,
gfp_flags);
@@ -670,36 +697,29 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
/* HW restriction regarding TRB size (8KB) */
if (req->request.length < 0x2000) {
dev_err(mdwc->dev, "%s: Min TRB size is 8KB\n", __func__);
+ spin_unlock_irqrestore(&dwc->lock, flags);
return -EINVAL;
}
- spin_lock_irqsave(&dwc->lock, flags);
- if (!dep->endpoint.desc) {
- dev_err(mdwc->dev,
- "%s: trying to queue request %p to disabled ep %s\n",
- __func__, request, ep->name);
- return -EPERM;
- }
-
if (dep->number == 0 || dep->number == 1) {
dev_err(mdwc->dev,
"%s: trying to queue dbm request %p to control ep %s\n",
__func__, request, ep->name);
+ spin_unlock_irqrestore(&dwc->lock, flags);
return -EPERM;
}
-
if (dep->busy_slot != dep->free_slot || !list_empty(&dep->request_list)
|| !list_empty(&dep->req_queued)) {
dev_err(mdwc->dev,
"%s: trying to queue dbm request %p tp ep %s\n",
__func__, request, ep->name);
+ spin_unlock_irqrestore(&dwc->lock, flags);
return -EPERM;
}
dep->busy_slot = 0;
dep->free_slot = 0;
- spin_unlock_irqrestore(&dwc->lock, flags);
/*
* Override req->complete function, but before doing that,
* store it's original pointer in the req_complete_list.
@@ -707,6 +727,7 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
req_complete = kzalloc(sizeof(*req_complete), gfp_flags);
if (!req_complete) {
dev_err(mdwc->dev, "%s: not enough memory\n", __func__);
+ spin_unlock_irqrestore(&dwc->lock, flags);
return -ENOMEM;
}
req_complete->req = request;
@@ -722,22 +743,6 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTADRHI(0)),
DWC3_GEVNTSIZ_SIZE(size));
- /*
- * We must obtain the lock of the dwc3 core driver,
- * including disabling interrupts, so we will be sure
- * that we are the only ones that configure the HW device
- * core and ensure that we queuing the request will finish
- * as soon as possible so we will release back the lock.
- */
- spin_lock_irqsave(&dwc->lock, flags);
- if (!dep->endpoint.desc) {
- dev_err(mdwc->dev,
- "%s: trying to queue request %p to disabled ep %s\n",
- __func__, request, ep->name);
- ret = -EPERM;
- goto err;
- }
-
ret = __dwc3_msm_ep_queue(dep, req);
if (ret < 0) {
dev_err(mdwc->dev,
@@ -2380,6 +2385,12 @@ static int dwc3_msm_power_set_property_usb(struct power_supply *psy,
if (mdwc->id_state == id)
break;
+ if (disable_host_mode && !id) {
+ dev_dbg(mdwc->dev, "%s: Ignoring ID change event :%d\n",
+ __func__, mdwc->id_state);
+ break;
+ }
+
/* Let OTG know about ID detection */
mdwc->id_state = id;
dbg_event(0xFF, "id_state", mdwc->id_state);
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 998885649d27..4afaaaadff31 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -7,7 +7,7 @@ ccflags-y += -I$(srctree)/drivers/usb/gadget/udc -I$(srctree)/drivers/usb/gad
obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o
libcomposite-y := usbstring.o config.o epautoconf.o
-libcomposite-y += composite.o functions.o configfs.o u_f.o
+libcomposite-y += composite.o functions.o u_f.o
obj-y += debug.o
g_android-y := android.o
diff --git a/drivers/usb/gadget/function/f_accessory.c b/drivers/usb/gadget/function/f_accessory.c
index 210b66c51afa..2f4a3626aa5f 100644
--- a/drivers/usb/gadget/function/f_accessory.c
+++ b/drivers/usb/gadget/function/f_accessory.c
@@ -1293,13 +1293,13 @@ static int acc_setup(void)
INIT_DELAYED_WORK(&dev->start_work, acc_start_work);
INIT_WORK(&dev->hid_work, acc_hid_work);
- /* _acc_dev must be set before calling usb_gadget_register_driver */
- _acc_dev = dev;
-
ret = misc_register(&acc_device);
if (ret)
goto err;
+ /* _acc_dev must be set before calling usb_gadget_register_driver */
+ _acc_dev = dev;
+
return 0;
err:
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 9922e7d12bdd..e9a66f93f2e0 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -2857,10 +2857,8 @@ static int _ffs_func_bind(struct usb_configuration *c,
struct ffs_data *ffs = func->ffs;
const int full = !!func->ffs->fs_descs_count;
- const int high = gadget_is_dualspeed(func->gadget) &&
- func->ffs->hs_descs_count;
- const int super = gadget_is_superspeed(func->gadget) &&
- func->ffs->ss_descs_count;
+ const int high = func->ffs->hs_descs_count;
+ const int super = func->ffs->ss_descs_count;
int fs_len, hs_len, ss_len, ret, i;
@@ -3576,8 +3574,6 @@ static void ffs_closed(struct ffs_data *ffs)
|| !atomic_read(&opts->func_inst.group.cg_item.ci_kref.refcount))
goto done;
- unregister_gadget_item(ffs_obj->opts->
- func_inst.group.cg_item.ci_parent->ci_parent);
done:
ffs_dev_unlock();
}
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index cf42842c542e..0d636008bb4b 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -3645,7 +3645,6 @@ static void fsg_lun_drop(struct config_group *group, struct config_item *item)
struct config_item *gadget;
gadget = group->cg_item.ci_parent->ci_parent;
- unregister_gadget_item(gadget);
}
fsg_common_remove_lun(lun_opts->lun, fsg_opts->common->sysfs);
diff --git a/drivers/usb/gadget/function/f_qdss.c b/drivers/usb/gadget/function/f_qdss.c
index 6ce347871d11..fcd590b4e7d3 100644
--- a/drivers/usb/gadget/function/f_qdss.c
+++ b/drivers/usb/gadget/function/f_qdss.c
@@ -1107,32 +1107,37 @@ EXPORT_SYMBOL(usb_qdss_open);
void usb_qdss_close(struct usb_qdss_ch *ch)
{
struct f_qdss *qdss = ch->priv_usb;
- struct usb_gadget *gadget = qdss->cdev->gadget;
+ struct usb_gadget *gadget;
unsigned long flags;
int status;
pr_debug("usb_qdss_close\n");
spin_lock_irqsave(&qdss_lock, flags);
+ if (!qdss || !qdss->usb_connected) {
+ ch->app_conn = 0;
+ spin_unlock_irqrestore(&qdss_lock, flags);
+ return;
+ }
+
usb_ep_dequeue(qdss->port.data, qdss->endless_req);
usb_ep_free_request(qdss->port.data, qdss->endless_req);
qdss->endless_req = NULL;
+ gadget = qdss->cdev->gadget;
ch->app_conn = 0;
spin_unlock_irqrestore(&qdss_lock, flags);
- if (qdss->usb_connected) {
- status = uninit_data(qdss->port.data);
- if (status)
- pr_err("%s: uninit_data error\n", __func__);
+ status = uninit_data(qdss->port.data);
+ if (status)
+ pr_err("%s: uninit_data error\n", __func__);
- status = set_qdss_data_connection(
+ status = set_qdss_data_connection(
gadget,
qdss->port.data,
qdss->port.data->address,
0);
- if (status)
- pr_err("%s:qdss_disconnect error\n", __func__);
- }
+ if (status)
+ pr_err("%s:qdss_disconnect error\n", __func__);
usb_gadget_restart(gadget);
}
EXPORT_SYMBOL(usb_qdss_close);
diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c
index a138f948324c..1d89e3045f2a 100644
--- a/drivers/usb/gadget/function/f_rndis.c
+++ b/drivers/usb/gadget/function/f_rndis.c
@@ -1150,8 +1150,6 @@ static struct usb_function_instance *rndis_alloc_inst(void)
descs[0] = &opts->rndis_os_desc;
names[0] = "rndis";
- usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
- names, THIS_MODULE);
config_group_init_type_name(&opts->func_inst.group, "",
&rndis_func_type);
diff --git a/drivers/usb/gadget/function/f_serial.c b/drivers/usb/gadget/function/f_serial.c
index 23f35856685d..25963de5777e 100644
--- a/drivers/usb/gadget/function/f_serial.c
+++ b/drivers/usb/gadget/function/f_serial.c
@@ -1395,6 +1395,13 @@ static long gser_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
smd_port_num =
gserial_ports[gser->port_num].client_port_num;
+ if (smd_write_arg.size > GSERIAL_BUF_LEN) {
+ pr_err("%s: Invalid size:%u, max: %u", __func__,
+ smd_write_arg.size, GSERIAL_BUF_LEN);
+ ret = -EINVAL;
+ break;
+ }
+
pr_debug("%s: Copying %d bytes from user buffer to local\n",
__func__, smd_write_arg.size);
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d1d60e02e723..9ac96f365600 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -526,6 +526,8 @@ static int ehci_init(struct usb_hcd *hcd)
hw->hw_alt_next = QTD_NEXT(ehci, ehci->async->dummy->qtd_dma);
/* clear interrupt enables, set irq latency */
+ log2_irq_thresh = ehci->log2_irq_thresh;
+
if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
log2_irq_thresh = 0;
temp = 1 << (16 + log2_irq_thresh);
@@ -778,6 +780,12 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
pstatus = ehci_readl(ehci,
&ehci->regs->port_status[i]);
+ /*set RS bit in case of remote wakeup*/
+ if (ehci_is_TDI(ehci) && !(cmd & CMD_RUN) &&
+ (pstatus & PORT_SUSPEND))
+ ehci_writel(ehci, cmd | CMD_RUN,
+ &ehci->regs->command);
+
if (pstatus & PORT_OWNER)
continue;
if (!(test_bit(i, &ehci->suspended_ports) &&
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 51c022d5ae54..7baa8846d6cf 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -275,6 +275,14 @@ int ehci_bus_suspend (struct usb_hcd *hcd)
if (t1 & PORT_OWNER)
set_bit(port, &ehci->owned_ports);
else if ((t1 & PORT_PE) && !(t1 & PORT_SUSPEND)) {
+ /* clear RS bit before setting SUSP bit
+ * and wait for HCH to get set. */
+ if (ehci->susp_sof_bug) {
+ spin_unlock_irq(&ehci->lock);
+ ehci_halt(ehci);
+ spin_lock_irq(&ehci->lock);
+ }
+
t2 |= PORT_SUSPEND;
set_bit(port, &ehci->bus_suspended);
}
@@ -338,8 +346,9 @@ int ehci_bus_suspend (struct usb_hcd *hcd)
if (ehci->bus_suspended)
udelay(150);
- /* turn off now-idle HC */
- ehci_halt (ehci);
+ /* if this bit is set, controller is already haled */
+ if (!ehci->susp_sof_bug)
+ ehci_halt(ehci); /* turn off now-idle HC */
spin_lock_irq(&ehci->lock);
if (ehci->enabled_hrtimer_events & BIT(EHCI_HRTIMER_POLL_DEAD))
@@ -1179,7 +1188,11 @@ int ehci_hub_control(
*/
temp &= ~PORT_WKCONN_E;
temp |= PORT_WKDISC_E | PORT_WKOC_E;
- ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
+ if (ehci->susp_sof_bug)
+ ehci_writel(ehci, temp, status_reg);
+ else
+ ehci_writel(ehci, temp | PORT_SUSPEND,
+ status_reg);
if (ehci->has_tdi_phy_lpm) {
spin_unlock_irqrestore(&ehci->lock, flags);
msleep(5);/* 5ms for HCD enter low pwr mode */
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index ff9536a0bc76..ad591ec4a99e 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -1,6 +1,6 @@
/* ehci-msm-hsic.c - HSUSB Host Controller Driver Implementation
*
- * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
*
* Partly derived from ehci-fsl.c and ehci-hcd.c
* Copyright (c) 2000-2004 by David Brownell
@@ -92,6 +92,7 @@ struct msm_hsic_hcd {
int wakeup_irq;
bool wakeup_irq_enabled;
int async_irq;
+ void __iomem *tlmm_regs;
uint32_t async_int_cnt;
atomic_t pm_usage_cnt;
uint32_t bus_perf_client;
@@ -642,14 +643,7 @@ static void msm_hsic_clk_reset(struct msm_hsic_hcd *mehci)
}
}
-#define IOMEM(x) ((void __force __iomem *)(x))
-#define MSM_TLMM_BASE IOMEM(0xFA017000)
-#define HSIC_STROBE_GPIO_PAD_CTL (MSM_TLMM_BASE+0x20C0)
-#define HSIC_DATA_GPIO_PAD_CTL (MSM_TLMM_BASE+0x20C4)
-#define HSIC_CAL_PAD_CTL (MSM_TLMM_BASE+0x20C8)
-#define HSIC_LV_MODE 0x04
#define HSIC_PAD_CALIBRATION 0xA8
-#define HSIC_GPIO_PAD_VAL 0x0A0AAA10
#define LINK_RESET_TIMEOUT_USEC (250 * 1000)
static void msm_hsic_phy_reset(struct msm_hsic_hcd *mehci)
@@ -666,8 +660,8 @@ static void msm_hsic_phy_reset(struct msm_hsic_hcd *mehci)
static int msm_hsic_start(struct msm_hsic_hcd *mehci)
{
struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
- int ret;
- void __iomem *reg;
+ int ret, *seq, seq_count;
+ u32 val;
if (mehci->hsic_pinctrl) {
ret = msm_hsic_config_pinctrl(mehci, 1);
@@ -687,13 +681,22 @@ static int msm_hsic_start(struct msm_hsic_hcd *mehci)
}
/* HSIC init sequence when HSIC signals (Strobe/Data) are
- routed via GPIOs */
- if (pdata && ((pdata->strobe && pdata->data) || mehci->hsic_pinctrl)) {
-
- if (!pdata->ignore_cal_pad_config) {
- /* Enable LV_MODE in HSIC_CAL_PAD_CTL register */
- writel_relaxed(HSIC_LV_MODE, HSIC_CAL_PAD_CTL);
- mb();
+ routed via TLMM */
+ if (mehci->tlmm_regs) {
+ /* Program TLMM pad configuration for HSIC */
+ seq = pdata->tlmm_init_seq;
+ seq_count = pdata->tlmm_seq_count;
+ if (seq && seq_count) {
+ while (seq[0] >= 0 && seq_count > 0) {
+ val = readl_relaxed(mehci->tlmm_regs + seq[0]);
+ val |= seq[1];
+ dev_dbg(mehci->dev, "%s: writing %x to %p\n",
+ __func__,
+ val, mehci->tlmm_regs + seq[0]);
+ writel_relaxed(val, mehci->tlmm_regs + seq[0]);
+ seq += 2;
+ seq_count -= 2;
+ }
}
/*set periodic calibration interval to ~2.048sec in
@@ -703,30 +706,13 @@ static int msm_hsic_start(struct msm_hsic_hcd *mehci)
/* Enable periodic IO calibration in HSIC_CFG register */
ulpi_write(mehci, HSIC_PAD_CALIBRATION, 0x30);
- /* Configure GPIO pins for HSIC functionality mode */
- ret = msm_hsic_config_gpios(mehci, 1);
- if (ret) {
- dev_err(mehci->dev, " gpio configuarion failed\n");
- goto free_resume_gpio;
- }
- if (pdata->strobe_pad_offset) {
- /* Set CORE_CTL_EN in STROBE GPIO PAD_CTL register */
- reg = MSM_TLMM_BASE + pdata->strobe_pad_offset;
- writel_relaxed(readl_relaxed(reg) | 0x2000000, reg);
- } else {
- /* Set LV_MODE=0x1 and DCC=0x2 in STROBE GPIO PAD_CTL */
- reg = HSIC_STROBE_GPIO_PAD_CTL;
- writel_relaxed(HSIC_GPIO_PAD_VAL, reg);
- }
-
- if (pdata->data_pad_offset) {
- /* Set CORE_CTL_EN in HSIC_DATA GPIO PAD_CTL register */
- reg = MSM_TLMM_BASE + pdata->data_pad_offset;
- writel_relaxed(readl_relaxed(reg) | 0x2000000, reg);
- } else {
- /* Set LV_MODE=0x1 and DCC=0x2 in STROBE GPIO PAD_CTL */
- reg = HSIC_DATA_GPIO_PAD_CTL;
- writel_relaxed(HSIC_GPIO_PAD_VAL, reg);
+ if (pdata->strobe && pdata->data) {
+ /* Configure GPIO pins for HSIC functionality mode */
+ ret = msm_hsic_config_gpios(mehci, 1);
+ if (ret) {
+ dev_err(mehci->dev, " gpio configuarion failed\n");
+ goto free_resume_gpio;
+ }
}
mb();
@@ -1522,7 +1508,7 @@ static struct hc_driver msm_hsic_driver = {
* generic hardware linkage
*/
.irq = msm_hsic_irq,
- .flags = HCD_USB2 | HCD_MEMORY,
+ .flags = HCD_USB2 | HCD_MEMORY | HCD_RT_OLD_ENUM | HCD_BH,
.reset = ehci_hsic_reset,
.start = ehci_run,
@@ -1558,6 +1544,7 @@ static struct hc_driver msm_hsic_driver = {
.bus_suspend = ehci_hsic_bus_suspend,
.bus_resume = ehci_hsic_bus_resume,
+ .log_urb = dbg_log_event,
.dump_regs = dump_hsic_regs,
.set_autosuspend_delay = ehci_msm_set_autosuspend_delay,
@@ -1628,15 +1615,6 @@ static int msm_hsic_init_clocks(struct msm_hsic_hcd *mehci, u32 init)
if (IS_ERR(mehci->inactivity_clk))
dev_dbg(mehci->dev, "failed to get inactivity_clk\n");
- /*
- * alt_core_clk is for LINK to be used during PHY RESET in
- * targets on which link does NOT use asynchronous reset methodology.
- * clock rate appropriately set by target specific clock driver
- */
- mehci->alt_core_clk = devm_clk_get(mehci->dev, "alt_core_clk");
- if (IS_ERR(mehci->alt_core_clk))
- dev_dbg(mehci->dev, "failed to get alt_core_clk\n");
-
ret = clk_set_rate(mehci->core_clk,
clk_round_rate(mehci->core_clk, LONG_MAX));
if (ret)
@@ -1647,13 +1625,6 @@ static int msm_hsic_init_clocks(struct msm_hsic_hcd *mehci, u32 init)
if (ret)
dev_err(mehci->dev, "failed to set phy_clk rate\n");
- if (!IS_ERR(mehci->alt_core_clk)) {
- ret = clk_set_rate(mehci->alt_core_clk,
- clk_round_rate(mehci->alt_core_clk, LONG_MAX));
- if (ret)
- dev_err(mehci->dev, "failed to set_rate alt_core_clk\n");
- }
-
ret = clk_set_rate(mehci->cal_clk,
clk_round_rate(mehci->cal_clk, LONG_MAX));
if (ret)
@@ -1989,12 +1960,6 @@ struct msm_hsic_host_platform_data *msm_hsic_dt_to_pdata(
"qcom,phy-susp-sof-workaround");
pdata->phy_reset_sof_workaround = of_property_read_bool(node,
"qcom,phy-reset-sof-workaround");
- pdata->ignore_cal_pad_config = of_property_read_bool(node,
- "hsic,ignore-cal-pad-config");
- of_property_read_u32(node, "hsic,strobe-pad-offset",
- &pdata->strobe_pad_offset);
- of_property_read_u32(node, "hsic,data-pad-offset",
- &pdata->data_pad_offset);
of_property_read_u32(node, "hsic,reset-delay",
&pdata->reset_delay);
of_property_read_u32(node, "hsic,log2-itc",
@@ -2028,7 +1993,7 @@ static int ehci_hsic_msm_probe(struct platform_device *pdev)
struct msm_hsic_hcd *mehci;
struct msm_hsic_host_platform_data *pdata;
unsigned long wakeup_irq_flags = 0;
- int ret;
+ int ret, len;
dev_dbg(&pdev->dev, "ehci_msm-hsic probe\n");
@@ -2093,6 +2058,19 @@ static int ehci_hsic_msm_probe(struct platform_device *pdev)
pdata = mehci->dev->platform_data;
platform_set_drvdata(pdev, hcd);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res && pdata->tlmm_init_seq) {
+ dev_err(&pdev->dev, "Unable to get TLMM memory resource\n");
+ ret = -ENODEV;
+ goto unmap;
+ } else if (res) {
+ mehci->tlmm_regs = ioremap(res->start, resource_size(res));
+ if (IS_ERR(mehci->tlmm_regs)) {
+ ret = PTR_ERR(mehci->tlmm_regs);
+ goto unmap;
+ }
+ }
+
spin_lock_init(&mehci->wakeup_lock);
if (pdata->phy_sof_workaround) {
@@ -2145,6 +2123,22 @@ static int ehci_hsic_msm_probe(struct platform_device *pdev)
goto unmap;
}
+ of_get_property(mehci->dev->of_node, "qcom,hsic-tlmm-init-seq", &len);
+ if (len) {
+ pdata->tlmm_init_seq = devm_kzalloc(&pdev->dev, len,
+ GFP_KERNEL);
+ if (!pdata->tlmm_init_seq)
+ return -ENODEV;
+ pdata->tlmm_seq_count = len / sizeof(*pdata->tlmm_init_seq);
+ ret = of_property_read_u32_array(mehci->dev->of_node,
+ "qcom,hsic-tlmm-init-seq",
+ pdata->tlmm_init_seq, pdata->tlmm_seq_count);
+ if (ret) {
+ dev_err(&pdev->dev, "hsic init-seq failed:%d\n", ret);
+ pdata->tlmm_seq_count = 0;
+ }
+ }
+
ret = msm_hsic_init_vddcx(mehci, 1);
if (ret) {
dev_err(&pdev->dev, "unable to initialize VDDCX\n");
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 965eb17f3924..d530a99ed3e5 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -300,13 +300,19 @@ static int xhci_plat_runtime_suspend(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ int ret;
if (!xhci)
return 0;
dev_dbg(dev, "xhci-plat runtime suspend\n");
- return xhci_suspend(xhci, true);
+ disable_irq(hcd->irq);
+ ret = xhci_suspend(xhci, true);
+ if (ret)
+ enable_irq(hcd->irq);
+
+ return ret;
}
static int xhci_plat_runtime_resume(struct device *dev)
@@ -321,6 +327,7 @@ static int xhci_plat_runtime_resume(struct device *dev)
dev_dbg(dev, "xhci-plat runtime resume\n");
ret = xhci_resume(xhci, false);
+ enable_irq(hcd->irq);
pm_runtime_mark_last_busy(dev);
return ret;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 3986eef398bd..a7e5a084a603 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -949,6 +949,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
if (xhci_handshake(xhci, &xhci->op_regs->status,
STS_HALT, STS_HALT, delay)) {
xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");
+ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
spin_unlock_irq(&xhci->lock);
return -ETIMEDOUT;
}
@@ -964,6 +966,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
if (xhci_handshake(xhci, &xhci->op_regs->status,
STS_SAVE, 0, 10 * 1000)) {
xhci_warn(xhci, "WARN: xHC save state timeout\n");
+ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
spin_unlock_irq(&xhci->lock);
return -ETIMEDOUT;
}
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 2082ac893c37..9bd7e29a8aba 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -158,7 +158,6 @@ enum mdss_hw_quirk {
MDSS_QUIRK_DSC_RIGHT_ONLY_PU,
MDSS_QUIRK_DSC_2SLICE_PU_THRPUT,
MDSS_QUIRK_DMA_BI_DIR,
- MDSS_QUIRK_MIN_BUS_VOTE,
MDSS_QUIRK_FMT_PACK_PATTERN,
MDSS_QUIRK_NEED_SECURE_MAP,
MDSS_QUIRK_SRC_SPLIT_ALWAYS,
@@ -354,6 +353,10 @@ struct mdss_data_type {
u32 rot_block_size;
+ /* HW RT bus (AXI) */
+ u32 hw_rt_bus_hdl;
+ u32 hw_rt_bus_ref_cnt;
+
/* data bus (AXI) */
u32 bus_hdl;
u32 bus_ref_cnt;
@@ -374,6 +377,7 @@ struct mdss_data_type {
u32 ao_bw_uc_idx; /* active only idx */
struct msm_bus_scale_pdata *bus_scale_table;
struct msm_bus_scale_pdata *reg_bus_scale_table;
+ struct msm_bus_scale_pdata *hw_rt_bus_scale_table;
u32 max_bw_low;
u32 max_bw_high;
u32 max_bw_per_pipe;
diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c
index abad4e135184..b18c2e210b04 100644
--- a/drivers/video/msm/mdss/mdss_debug.c
+++ b/drivers/video/msm/mdss/mdss_debug.c
@@ -1390,6 +1390,9 @@ void mdss_misr_disable(struct mdss_data_type *mdata,
map = mdss_misr_get_map(req->block_id, ctl, mdata,
ctl->is_video_mode);
+ if (!map)
+ return;
+
/* clear the map data */
memset(map->crc_ping, 0, sizeof(map->crc_ping));
memset(map->crc_pong, 0, sizeof(map->crc_pong));
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index cf66127a8bb4..696cd953058e 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -2892,6 +2892,12 @@ static int mdss_dsi_cont_splash_config(struct mdss_panel_info *pinfo,
mdss_dsi_panel_pwm_enable(ctrl_pdata);
ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT |
CTRL_STATE_MDP_ACTIVE | CTRL_STATE_DSI_ACTIVE);
+
+ /*
+ * MDP client removes this extra vote during splash reconfigure
+ * for command mode panel from interface. DSI removes the vote
+ * during suspend-resume for video mode panel.
+ */
if (ctrl_pdata->panel_data.panel_info.type == MIPI_CMD_PANEL)
clk_handle = ctrl_pdata->mdp_clk_handle;
else
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index 72ed1d38c4cd..9876ac354867 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -527,7 +527,8 @@ struct mdss_dsi_ctrl_pdata {
void *clk_mngr;
void *dsi_clk_handle;
void *mdp_clk_handle;
- int m_vote_cnt;
+ int m_dsi_vote_cnt;
+ int m_mdp_vote_cnt;
/* debugfs structure */
struct mdss_dsi_debugfs_info *debugfs_info;
diff --git a/drivers/video/msm/mdss/mdss_dsi_clk.c b/drivers/video/msm/mdss/mdss_dsi_clk.c
index 727d6707444c..377aeb7cad47 100644
--- a/drivers/video/msm/mdss/mdss_dsi_clk.c
+++ b/drivers/video/msm/mdss/mdss_dsi_clk.c
@@ -722,8 +722,30 @@ error:
return rc;
}
+bool is_dsi_clk_in_ecg_state(void *client)
+{
+ struct mdss_dsi_clk_client_info *c = client;
+ struct mdss_dsi_clk_mngr *mngr;
+ bool is_ecg = false;
+
+
+ if (!client) {
+ pr_err("Invalid client params\n");
+ goto end;
+ }
+
+ mngr = c->mngr;
+
+ mutex_lock(&mngr->clk_mutex);
+ is_ecg = (c->core_clk_state == MDSS_DSI_CLK_EARLY_GATE);
+ mutex_unlock(&mngr->clk_mutex);
+
+end:
+ return is_ecg;
+}
+
int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk,
- enum mdss_dsi_clk_state state)
+ enum mdss_dsi_clk_state state, u32 index)
{
int rc = 0;
struct mdss_dsi_clk_client_info *c = client;
@@ -744,7 +766,7 @@ int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk,
c->name, mngr->name, clk, state, c->core_clk_state,
c->link_clk_state);
- MDSS_XLOG(clk, state, c->core_clk_state, c->link_clk_state);
+ MDSS_XLOG(index, clk, state, c->core_clk_state, c->link_clk_state);
/*
* Refcount handling rules:
* 1. Increment refcount whenever ON is called
@@ -810,7 +832,7 @@ int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk,
pr_debug("[%s]%s: change=%d, Core (ref=%d, state=%d), Link (ref=%d, state=%d)\n",
c->name, mngr->name, changed, c->core_refcount,
c->core_clk_state, c->link_refcount, c->link_clk_state);
- MDSS_XLOG(clk, state, c->core_clk_state, c->link_clk_state);
+ MDSS_XLOG(index, clk, state, c->core_clk_state, c->link_clk_state);
if (changed) {
rc = dsi_recheck_clk_state(mngr);
diff --git a/drivers/video/msm/mdss/mdss_dsi_clk.h b/drivers/video/msm/mdss/mdss_dsi_clk.h
index d42228b48171..8478426a815b 100644
--- a/drivers/video/msm/mdss/mdss_dsi_clk.h
+++ b/drivers/video/msm/mdss/mdss_dsi_clk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -194,6 +194,7 @@ int mdss_dsi_clk_deregister(void *client);
* @client: client handle.
* @clk: Type of clock requested (enum mdss_dsi_clk_type).
* @state: clock state requested.
+ * @index: controller index.
*
* This routine is used to request a new clock state for a specific clock. If
* turning ON the clocks, this guarantees that clocks will be on before
@@ -203,7 +204,7 @@ int mdss_dsi_clk_deregister(void *client);
* @return: error code.
*/
int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk,
- enum mdss_dsi_clk_state state);
+ enum mdss_dsi_clk_state state, u32 index);
/**
* mdss_dsi_clk_set_link_rate() - set clock rate for link clocks
@@ -235,4 +236,16 @@ int mdss_dsi_clk_set_link_rate(void *client, enum mdss_dsi_link_clk_type clk,
* @return:error code.
*/
int mdss_dsi_clk_force_toggle(void *client, u32 clk);
+
+/**
+ * is_dsi_clk_in_ecg_state() - Checks the current state of clocks
+ * @client: client handle.
+ *
+ * This routine returns checks the clocks status for client and return
+ * success code based on it.
+ *
+ * @return:true: if clocks are in ECG state
+ * false: for all other cases
+ */
+bool is_dsi_clk_in_ecg_state(void *client);
#endif /* _MDSS_DSI_CLK_H_ */
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 4e1e1782dccf..0573e3bed919 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -2785,12 +2785,6 @@ static int dsi_event_thread(void *data)
pr_debug("%s: Handling underflow event\n",
__func__);
__dsi_fifo_error_handler(ctrl, true);
- } else {
- pr_err("%s: ctrl recovery not defined\n",
- __func__);
- MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl",
- "dsi0_phy", "dsi1_ctrl", "dsi1_phy", "vbif",
- "vbif_nrt", "dbg_bus", "vbif_dbg_bus", "panic");
}
mutex_unlock(&ctrl->mutex);
}
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index 83d1be33b770..058e09577150 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -373,7 +373,7 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable)
}
if (gpio_is_valid(ctrl_pdata->mode_gpio)) {
- bool out;
+ bool out = false;
if (pinfo->mode_gpio_state == MODE_GPIO_HIGH)
out = true;
@@ -1819,6 +1819,9 @@ static int mdss_dsi_parse_panel_features(struct device_node *np,
pinfo->panel_ack_disabled = pinfo->sim_panel_mode ?
1 : of_property_read_bool(np, "qcom,panel-ack-disabled");
+ pinfo->allow_phy_power_off = of_property_read_bool(np,
+ "qcom,panel-allow-phy-poweroff");
+
mdss_dsi_parse_esd_params(np, ctrl);
if (pinfo->panel_ack_disabled && pinfo->esd_check_enabled) {
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index e9a6ad7dacaf..0151598de8e3 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -3707,7 +3707,7 @@ static int mdss_fb_set_par(struct fb_info *info)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
struct fb_var_screeninfo *var = &info->var;
- int old_imgType;
+ int old_imgType, old_format;
int ret = 0;
ret = mdss_fb_pan_idle(mfd);
@@ -3790,6 +3790,12 @@ static int mdss_fb_set_par(struct fb_info *info)
mfd->fbi->fix.smem_len = PAGE_ALIGN(mfd->fbi->fix.line_length *
mfd->fbi->var.yres) * mfd->fb_page;
+ old_format = mdss_grayscale_to_mdp_format(var->grayscale);
+ if (!IS_ERR_VALUE(old_format)) {
+ if (old_format != mfd->panel_info->out_format)
+ mfd->panel_reconfig = true;
+ }
+
if (mfd->panel_reconfig || (mfd->fb_imgType != old_imgType)) {
mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable);
mdss_fb_var_to_panelinfo(var, mfd->panel_info);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.c b/drivers/video/msm/mdss/mdss_hdmi_edid.c
index f5c45571f0d2..36c24302658d 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.c
@@ -2346,6 +2346,24 @@ bool hdmi_edid_get_scdc_support(void *input)
return scdc_present;
}
+/**
+ * hdmi_edid_sink_scramble_override() - check if override has been enabled
+ * @input: edid data
+ *
+ * Return true if scrambling override is enabled false otherwise.
+ */
+bool hdmi_edid_sink_scramble_override(void *input)
+{
+ struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input;
+
+ if (edid_ctrl->edid_override &&
+ (edid_ctrl->override_data.scramble != -1))
+ return true;
+
+ return false;
+
+}
+
bool hdmi_edid_get_sink_scrambler_support(void *input)
{
struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.h b/drivers/video/msm/mdss/mdss_hdmi_edid.h
index d485e370d3aa..368df21ba457 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2016, 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
@@ -32,6 +32,7 @@ int hdmi_edid_parser(void *edid_ctrl);
u32 hdmi_edid_get_raw_data(void *edid_ctrl, u8 *buf, u32 size);
u8 hdmi_edid_get_sink_scaninfo(void *edid_ctrl, u32 resolution);
u32 hdmi_edid_get_sink_mode(void *edid_ctrl);
+bool hdmi_edid_sink_scramble_override(void *input);
bool hdmi_edid_get_sink_scrambler_support(void *input);
bool hdmi_edid_get_scdc_support(void *input);
int hdmi_edid_get_audio_blk(void *edid_ctrl,
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index b300c4aba599..415b19533f16 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -77,6 +77,7 @@
#define HDMI_DEFAULT_MAX_PCLK_RATE 148500
#define HDMI_TX_3_MAX_PCLK_RATE 297000
#define HDMI_TX_4_MAX_PCLK_RATE 600000
+#define HDMI_TX_KHZ_TO_HZ 1000U
/* Enable HDCP by default */
static bool hdcp_feature_on = true;
@@ -90,6 +91,9 @@ static bool hdcp_feature_on = true;
#define VENDOR_IFRAME_LINE_NUMBER 3
#define MAX_EDID_READ_RETRY 5
+#define HDMI_TX_MIN_FPS 20000
+#define HDMI_TX_MAX_FPS 120000
+
enum {
DATA_BYTE_1,
DATA_BYTE_2,
@@ -162,6 +166,7 @@ static int hdmi_tx_enable_power(struct hdmi_tx_ctrl *hdmi_ctrl,
static int hdmi_tx_setup_tmds_clk_rate(struct hdmi_tx_ctrl *hdmi_ctrl);
static void hdmi_tx_set_vendor_specific_infoframe(
struct hdmi_tx_ctrl *hdmi_ctrl);
+static void hdmi_tx_fps_work(struct work_struct *work);
static struct mdss_hw hdmi_tx_hw = {
.hw_ndx = MDSS_HW_HDMI,
@@ -390,12 +395,15 @@ static int hdmi_tx_get_vic_from_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl,
new_vic = pinfo->vic;
DEV_DBG("%s: %s is supported\n", __func__,
msm_hdmi_mode_2string(new_vic));
+ pinfo->lcdc.frame_rate = info.refresh_rate;
} else {
DEV_ERR("%s: invalid or not supported vic %d\n",
__func__, pinfo->vic);
return -EPERM;
}
} else {
+ u64 pclk;
+
timing.active_h = pinfo->xres;
timing.back_porch_h = pinfo->lcdc.h_back_porch;
timing.front_porch_h = pinfo->lcdc.h_front_porch;
@@ -416,7 +424,10 @@ static int hdmi_tx_get_vic_from_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl,
timing.active_v, timing.back_porch_v,
timing.front_porch_v, timing.pulse_width_v, v_total);
- timing.pixel_freq = ((unsigned long int)pinfo->clk_rate / 1000);
+ pclk = pinfo->clk_rate;
+ do_div(pclk, HDMI_TX_KHZ_TO_HZ);
+
+ timing.pixel_freq = (unsigned long) pclk;
if (h_total && v_total) {
timing.refresh_rate = ((timing.pixel_freq * 1000) /
(h_total * v_total)) * 1000;
@@ -742,6 +753,41 @@ end:
return ret;
}
+static int hdmi_tx_update_pixel_clk(struct hdmi_tx_ctrl *hdmi_ctrl, int fps)
+{
+ struct dss_module_power *power_data = NULL;
+ struct mdss_panel_info *pinfo;
+ int rc = 0;
+
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ rc = -EINVAL;
+ goto end;
+ }
+
+ pinfo = &hdmi_ctrl->panel_data.panel_info;
+
+ power_data = &hdmi_ctrl->pdata.power_data[HDMI_TX_CORE_PM];
+ if (!power_data) {
+ DEV_ERR("%s: Error: invalid power data\n", __func__);
+ rc = -EINVAL;
+ goto end;
+ }
+
+ if (power_data->clk_config->rate == pinfo->clk_rate) {
+ rc = -EINVAL;
+ goto end;
+ }
+
+ power_data->clk_config->rate = pinfo->clk_rate;
+
+ DEV_DBG("%s: rate %ld\n", __func__, power_data->clk_config->rate);
+
+ msm_dss_clk_set_rate(power_data->clk_config, power_data->num_clk);
+end:
+ return rc;
+}
+
static ssize_t hdmi_tx_sysfs_wta_hot_plug(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
@@ -935,6 +981,9 @@ static ssize_t hdmi_tx_sysfs_wta_hpd(struct device *dev,
hdmi_tx_config_5v(hdmi_ctrl, false);
} else {
hdmi_tx_hpd_off(hdmi_ctrl);
+
+ hdmi_ctrl->sdev.state = 0;
+ hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
}
break;
@@ -1905,6 +1954,7 @@ static int hdmi_tx_init_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl)
pinfo->lcdc.v_back_porch = timing.back_porch_v;
pinfo->lcdc.v_front_porch = timing.front_porch_v;
pinfo->lcdc.v_pulse_width = timing.pulse_width_v;
+ pinfo->lcdc.frame_rate = timing.refresh_rate;
pinfo->type = DTV_PANEL;
pinfo->pdest = DISPLAY_3;
@@ -1912,6 +1962,9 @@ static int hdmi_tx_init_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl)
pinfo->bpp = 24;
pinfo->fb_num = 1;
+ pinfo->min_fps = HDMI_TX_MIN_FPS;
+ pinfo->max_fps = HDMI_TX_MAX_FPS;
+
pinfo->lcdc.border_clr = 0; /* blk */
pinfo->lcdc.underflow_clr = 0xff; /* blue */
pinfo->lcdc.hsync_skew = 0;
@@ -2105,6 +2158,18 @@ end:
return ret;
} /* hdmi_tx_check_capability */
+static void hdmi_tx_update_panel_data(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ struct mdss_panel_info *pinfo = &hdmi_ctrl->panel_data.panel_info;
+
+ pinfo->saved_total = mdss_panel_get_htotal(pinfo, true);
+ pinfo->saved_fporch = hdmi_ctrl->vid_cfg.timing.front_porch_h;
+
+ pinfo->current_fps = hdmi_ctrl->vid_cfg.timing.refresh_rate;
+ pinfo->default_fps = hdmi_ctrl->vid_cfg.timing.refresh_rate;
+ pinfo->lcdc.frame_rate = hdmi_ctrl->vid_cfg.timing.refresh_rate;
+}
+
static int hdmi_tx_set_video_fmt(struct hdmi_tx_ctrl *hdmi_ctrl,
struct mdss_panel_info *pinfo)
{
@@ -2183,9 +2248,27 @@ static int hdmi_tx_set_video_fmt(struct hdmi_tx_ctrl *hdmi_ctrl,
hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID],
vid_cfg->vic, false);
+ hdmi_tx_update_panel_data(hdmi_ctrl);
+
return res_changed;
} /* hdmi_tx_set_video_fmt */
+static bool hdmi_tx_check_for_video_update(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ struct msm_hdmi_mode_timing_info *timing = &hdmi_ctrl->vid_cfg.timing;
+ struct mdss_panel_info *pinfo = &hdmi_ctrl->panel_data.panel_info;
+
+ if (timing->back_porch_h != pinfo->lcdc.h_back_porch ||
+ timing->front_porch_h != pinfo->lcdc.h_front_porch ||
+ timing->pulse_width_h != pinfo->lcdc.h_pulse_width ||
+ timing->back_porch_v != pinfo->lcdc.v_back_porch ||
+ timing->front_porch_v != pinfo->lcdc.v_front_porch ||
+ timing->pulse_width_v != pinfo->lcdc.v_pulse_width)
+ return true;
+
+ return false;
+}
+
static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl)
{
u32 total_v = 0;
@@ -2197,6 +2280,7 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl)
u32 div = 0;
struct dss_io_data *io = NULL;
struct msm_hdmi_mode_timing_info *timing = NULL;
+ struct mdss_panel_info *pinfo;
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
@@ -2214,6 +2298,9 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl)
DEV_ERR("%s: Core io is not initialized\n", __func__);
return -EPERM;
}
+
+ pinfo = &hdmi_ctrl->panel_data.panel_info;
+
/*
* In case of YUV420 output, Horizontal timing parameters should be
* reduced by half
@@ -2221,6 +2308,35 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl)
if (hdmi_ctrl->vid_cfg.avi_iframe.pixel_format == MDP_Y_CBCR_H2V2)
div = 1;
+ if (pinfo->dynamic_fps) {
+ if (!hdmi_tx_check_for_video_update(hdmi_ctrl))
+ return -EINVAL;
+
+ if (pinfo->dfps_update ==
+ DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP ||
+ pinfo->dfps_update ==
+ DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) {
+ DEV_DBG("%s: hfp=%d, hbp=%d, hpw=%d\n", __func__,
+ pinfo->lcdc.h_front_porch,
+ pinfo->lcdc.h_back_porch,
+ pinfo->lcdc.h_pulse_width);
+
+ timing->back_porch_h = pinfo->lcdc.h_back_porch;
+ timing->front_porch_h = pinfo->lcdc.h_front_porch;
+ timing->pulse_width_h = pinfo->lcdc.h_pulse_width;
+ } else if (pinfo->dfps_update ==
+ DFPS_IMMEDIATE_PORCH_UPDATE_MODE_VFP) {
+ DEV_DBG("%s: vfp=%d, vbp=%d, vpw=%d\n", __func__,
+ pinfo->lcdc.v_front_porch,
+ pinfo->lcdc.v_back_porch,
+ pinfo->lcdc.v_pulse_width);
+
+ timing->back_porch_v = pinfo->lcdc.v_back_porch;
+ timing->front_porch_v = pinfo->lcdc.v_front_porch;
+ timing->pulse_width_v = pinfo->lcdc.v_pulse_width;
+ }
+ }
+
total_h = (hdmi_tx_get_h_total(timing) >> div) - 1;
total_v = hdmi_tx_get_v_total(timing) - 1;
@@ -3308,15 +3424,17 @@ int hdmi_tx_setup_scrambler(struct hdmi_tx_ctrl *hdmi_ctrl)
rate = hdmi_tx_setup_tmds_clk_rate(hdmi_ctrl);
- if (rate > HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ) {
- scrambler_on = true;
- tmds_clock_ratio = 1;
- } else {
- if (hdmi_edid_get_sink_scrambler_support(edid_data))
+ scrambler_on = hdmi_edid_get_sink_scrambler_support(edid_data);
+
+ if (!hdmi_edid_sink_scramble_override(edid_data)) {
+ if (rate > HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ)
scrambler_on = true;
}
if (scrambler_on) {
+ if (rate > HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ)
+ tmds_clock_ratio = 1;
+
rc = hdmi_scdc_write(&hdmi_ctrl->ddc_ctrl,
HDMI_TX_SCDC_TMDS_BIT_CLOCK_RATIO_UPDATE,
tmds_clock_ratio);
@@ -3957,6 +4075,7 @@ static int hdmi_tx_dev_init(struct hdmi_tx_ctrl *hdmi_ctrl)
init_completion(&hdmi_ctrl->hpd_int_done);
INIT_WORK(&hdmi_ctrl->hpd_int_work, hdmi_tx_hpd_int_work);
+ INIT_WORK(&hdmi_ctrl->fps_work, hdmi_tx_fps_work);
INIT_WORK(&hdmi_ctrl->cable_notify_work, hdmi_tx_cable_notify_work);
INIT_DELAYED_WORK(&hdmi_ctrl->hdcp_cb_work, hdmi_tx_hdcp_cb_work);
@@ -4088,6 +4207,127 @@ static char *hdmi_tx_get_event_name(int event)
}
}
+static void hdmi_tx_update_fps(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ int rc = 0, vic = 0;
+ u64 pclk;
+ struct mdss_panel_data *pdata;
+ struct mdss_panel_info *pinfo;
+ struct msm_hdmi_mode_timing_info timing = {0};
+
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return;
+ }
+
+ pdata = &hdmi_ctrl->panel_data;
+ pinfo = &pdata->panel_info;
+
+ if (!pinfo->dynamic_fps) {
+ DEV_DBG("%s: Dynamic fps not enabled\n", __func__);
+ return;
+ }
+
+ if (hdmi_ctrl->dynamic_fps == pinfo->current_fps) {
+ DEV_DBG("%s: Panel is already at this FPS: %d\n",
+ __func__, hdmi_ctrl->dynamic_fps);
+ return;
+ }
+
+ if (hdmi_tx_is_hdcp_enabled(hdmi_ctrl))
+ hdmi_tx_hdcp_off(hdmi_ctrl);
+
+ if (pinfo->dfps_update == DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) {
+ if (hdmi_tx_video_setup(hdmi_ctrl)) {
+ DEV_DBG("%s: no change in video timing\n", __func__);
+ return;
+ }
+
+ if (hdmi_tx_update_pixel_clk(hdmi_ctrl,
+ hdmi_ctrl->dynamic_fps)) {
+ DEV_DBG("%s: no change in clk\n", __func__);
+ return;
+ }
+
+ pinfo->saved_total = mdss_panel_get_htotal(pinfo, true);
+ pinfo->saved_fporch = pinfo->lcdc.h_front_porch;
+ } else if (pinfo->dfps_update == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP) {
+ if (hdmi_tx_video_setup(hdmi_ctrl)) {
+ DEV_DBG("%s: no change in video timing\n", __func__);
+ return;
+ }
+
+ pinfo->saved_total = mdss_panel_get_htotal(pinfo, true);
+ pinfo->saved_fporch = pinfo->lcdc.h_front_porch;
+ } else if (pinfo->dfps_update == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_VFP) {
+ if (hdmi_tx_video_setup(hdmi_ctrl)) {
+ DEV_DBG("%s: no change in video timing\n", __func__);
+ return;
+ }
+
+ pinfo->saved_total = mdss_panel_get_vtotal(pinfo);
+ pinfo->saved_fporch = pinfo->lcdc.v_front_porch;
+ } else if (pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
+ if (hdmi_tx_update_pixel_clk(hdmi_ctrl,
+ hdmi_ctrl->dynamic_fps)) {
+ DEV_DBG("%s: no change in clk\n", __func__);
+ return;
+ }
+ }
+
+ pinfo->current_fps = hdmi_ctrl->dynamic_fps;
+ pinfo->default_fps = hdmi_ctrl->dynamic_fps;
+ pinfo->lcdc.frame_rate = hdmi_ctrl->dynamic_fps;
+ pinfo->dynamic_fps = false;
+
+ rc = hdmi_get_supported_mode(&timing, &hdmi_ctrl->ds_data,
+ hdmi_ctrl->vid_cfg.vic);
+
+ if (rc || !timing.supported) {
+ DEV_ERR("%s: timing details\n", __func__);
+ return;
+ }
+
+ timing.back_porch_h = pinfo->lcdc.h_back_porch;
+ timing.front_porch_h = pinfo->lcdc.h_front_porch;
+ timing.pulse_width_h = pinfo->lcdc.h_pulse_width;
+
+ timing.back_porch_v = pinfo->lcdc.v_back_porch;
+ timing.front_porch_v = pinfo->lcdc.v_front_porch;
+ timing.pulse_width_v = pinfo->lcdc.v_pulse_width;
+
+ timing.refresh_rate = hdmi_ctrl->dynamic_fps;
+
+ pclk = pinfo->clk_rate;
+ do_div(pclk, HDMI_TX_KHZ_TO_HZ);
+ timing.pixel_freq = (unsigned long) pclk;
+
+ hdmi_ctrl->vid_cfg.timing = timing;
+
+ vic = hdmi_get_video_id_code(&timing, &hdmi_ctrl->ds_data);
+
+ if (vic > 0 && hdmi_ctrl->vid_cfg.vic != vic) {
+ hdmi_ctrl->vid_cfg.vic = vic;
+ DEV_DBG("%s: switched to new resolution id %d\n",
+ __func__, vic);
+ }
+
+ hdmi_tx_start_hdcp(hdmi_ctrl);
+}
+
+static void hdmi_tx_fps_work(struct work_struct *work)
+{
+ struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
+
+ hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, fps_work);
+ if (!hdmi_ctrl) {
+ DEV_DBG("%s: invalid input\n", __func__);
+ return;
+ }
+
+ hdmi_tx_update_fps(hdmi_ctrl);
+}
+
static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data,
int event, void *arg)
{
@@ -4100,6 +4340,13 @@ static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data,
return -EINVAL;
}
+ /* UPDATE FPS is called from atomic context */
+ if (event == MDSS_EVENT_PANEL_UPDATE_FPS) {
+ hdmi_ctrl->dynamic_fps = (u32) (unsigned long)arg;
+ queue_work(hdmi_ctrl->workq, &hdmi_ctrl->fps_work);
+ return rc;
+ }
+
mutex_lock(&hdmi_ctrl->tx_lock);
DEV_DBG("%s: event = %s suspend=%d, hpd_feature=%d\n", __func__,
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.h b/drivers/video/msm/mdss/mdss_hdmi_tx.h
index 170837dcc9e6..df2895244794 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.h
@@ -150,6 +150,7 @@ struct hdmi_tx_ctrl {
u32 hpd_feature_on;
u32 hpd_initialized;
u32 vote_hdmi_core_on;
+ u32 dynamic_fps;
u8 timing_gen_on;
u8 mhl_hpd_on;
u8 hdcp_status;
@@ -157,6 +158,7 @@ struct hdmi_tx_ctrl {
struct hdmi_util_ds_data ds_data;
struct completion hpd_int_done;
struct work_struct hpd_int_work;
+ struct work_struct fps_work;
struct delayed_work hdcp_cb_work;
struct work_struct cable_notify_work;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.c b/drivers/video/msm/mdss/mdss_hdmi_util.c
index 4640c3f505b6..555ba1ba5b1c 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.c
@@ -595,29 +595,13 @@ int hdmi_get_video_id_code(struct msm_hdmi_mode_timing_info *timing_in,
break;
}
- if (vic < 0) {
- for (i = 0; i < HDMI_VFRMT_MAX; i++) {
- ret = hdmi_get_supported_mode(&supported_timing,
- ds_data, i);
- if (ret || !supported_timing.supported)
- continue;
- if (timing_in->active_h != supported_timing.active_h)
- continue;
- if (timing_in->active_v != supported_timing.active_v)
- continue;
- vic = (int)supported_timing.video_format;
- break;
- }
- }
-
- if (vic < 0) {
+ if (vic < 0)
pr_err("timing is not supported h=%d v=%d\n",
timing_in->active_h, timing_in->active_v);
- }
-
+ else
+ pr_debug("vic = %d timing = %s\n", vic,
+ msm_hdmi_mode_2string((u32)vic));
exit:
- pr_debug("vic = %d timing = %s\n", vic,
- msm_hdmi_mode_2string((u32)vic));
return vic;
} /* hdmi_get_video_id_code */
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 18c6c01b50db..6347578b90c0 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -433,6 +433,18 @@ static int mdss_mdp_bus_scale_register(struct mdss_data_type *mdata)
mdata->reg_bus_hdl);
}
+ if (mdata->hw_rt_bus_scale_table && !mdata->hw_rt_bus_hdl) {
+ mdata->hw_rt_bus_hdl =
+ msm_bus_scale_register_client(
+ mdata->hw_rt_bus_scale_table);
+ if (!mdata->hw_rt_bus_hdl)
+ /* Continue without reg_bus scaling */
+ pr_warn("hw_rt_bus client register failed\n");
+ else
+ pr_debug("register hw_rt_bus=%x\n",
+ mdata->hw_rt_bus_hdl);
+ }
+
/*
* Following call will not result in actual vote rather update the
* current index and ab/ib value. When continuous splash is enabled,
@@ -454,6 +466,11 @@ static void mdss_mdp_bus_scale_unregister(struct mdss_data_type *mdata)
msm_bus_scale_unregister_client(mdata->reg_bus_hdl);
mdata->reg_bus_hdl = 0;
}
+
+ if (mdata->hw_rt_bus_hdl) {
+ msm_bus_scale_unregister_client(mdata->hw_rt_bus_hdl);
+ mdata->hw_rt_bus_hdl = 0;
+ }
}
/*
@@ -1155,6 +1172,54 @@ unsigned long mdss_mdp_get_clk_rate(u32 clk_idx, bool locked)
}
/**
+ * mdss_bus_rt_bw_vote() -- place bus bandwidth request
+ * @enable: value of enable or disable
+ *
+ * hw_rt table has two entries, 0 and Min Vote (1Mhz)
+ * while attaching SMMU and for few TZ operations which
+ * happen at very early stage, we will request Min Vote
+ * thru this handle.
+ *
+ */
+static int mdss_bus_rt_bw_vote(bool enable)
+{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ int rc = 0;
+ bool changed = false;
+
+ if (!mdata->hw_rt_bus_hdl)
+ return 0;
+
+ if (enable) {
+ if (mdata->hw_rt_bus_ref_cnt == 0)
+ changed = true;
+ mdata->hw_rt_bus_ref_cnt++;
+ } else {
+ if (mdata->hw_rt_bus_ref_cnt != 0) {
+ mdata->hw_rt_bus_ref_cnt--;
+ if (mdata->hw_rt_bus_ref_cnt == 0)
+ changed = true;
+ } else {
+ pr_warn("%s: bus bw votes are not balanced\n",
+ __func__);
+ }
+ }
+
+ pr_debug("%pS: task:%s bw_cnt=%d changed=%d enable=%d\n",
+ __builtin_return_address(0), current->group_leader->comm,
+ mdata->hw_rt_bus_ref_cnt, changed, enable);
+
+ if (changed) {
+ rc = msm_bus_scale_client_update_request(mdata->hw_rt_bus_hdl,
+ enable ? 1 : 0);
+ if (rc)
+ pr_err("%s: Bus bandwidth vote failed\n", __func__);
+ }
+
+ return rc;
+}
+
+/**
* __mdss_mdp_reg_access_clk_enable - Enable minimum MDSS clocks required
* for register access
*/
@@ -1164,9 +1229,7 @@ static inline void __mdss_mdp_reg_access_clk_enable(
if (enable) {
mdss_update_reg_bus_vote(mdata->reg_bus_clt,
VOTE_INDEX_LOW);
- if (mdss_has_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE))
- mdss_bus_scale_set_quota(MDSS_HW_RT,
- SZ_1M, SZ_1M);
+ mdss_bus_rt_bw_vote(true);
mdss_mdp_clk_update(MDSS_CLK_AHB, 1);
mdss_mdp_clk_update(MDSS_CLK_AXI, 1);
mdss_mdp_clk_update(MDSS_CLK_MDP_CORE, 1);
@@ -1174,8 +1237,7 @@ static inline void __mdss_mdp_reg_access_clk_enable(
mdss_mdp_clk_update(MDSS_CLK_MDP_CORE, 0);
mdss_mdp_clk_update(MDSS_CLK_AXI, 0);
mdss_mdp_clk_update(MDSS_CLK_AHB, 0);
- if (mdss_has_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE))
- mdss_bus_scale_set_quota(MDSS_HW_RT, 0, 0);
+ mdss_bus_rt_bw_vote(false);
mdss_update_reg_bus_vote(mdata->reg_bus_clt,
VOTE_INDEX_DISABLE);
}
@@ -1255,9 +1317,7 @@ int mdss_iommu_ctrl(int enable)
* finished handoff, as it may still be working with phys addr
*/
if (!mdata->iommu_attached && !mdata->handoff_pending) {
- if (mdss_has_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE))
- mdss_bus_scale_set_quota(MDSS_HW_RT,
- SZ_1M, SZ_1M);
+ mdss_bus_rt_bw_vote(true);
rc = mdss_smmu_attach(mdata);
}
mdata->iommu_ref_cnt++;
@@ -1266,10 +1326,7 @@ int mdss_iommu_ctrl(int enable)
mdata->iommu_ref_cnt--;
if (mdata->iommu_ref_cnt == 0) {
rc = mdss_smmu_detach(mdata);
- if (mdss_has_quirk(mdata,
- MDSS_QUIRK_MIN_BUS_VOTE))
- mdss_bus_scale_set_quota(MDSS_HW_RT,
- 0, 0);
+ mdss_bus_rt_bw_vote(false);
}
} else {
pr_err("unbalanced iommu ref\n");
@@ -1780,7 +1837,6 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
mdss_mdp_init_default_prefill_factors(mdata);
set_bit(MDSS_QOS_OTLIM, mdata->mdss_qos_map);
mdss_set_quirk(mdata, MDSS_QUIRK_DMA_BI_DIR);
- mdss_set_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE);
mdss_set_quirk(mdata, MDSS_QUIRK_NEED_SECURE_MAP);
break;
case MDSS_MDP_HW_REV_115:
@@ -1801,7 +1857,6 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
mdss_mdp_init_default_prefill_factors(mdata);
set_bit(MDSS_QOS_OTLIM, mdata->mdss_qos_map);
mdss_set_quirk(mdata, MDSS_QUIRK_DMA_BI_DIR);
- mdss_set_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE);
mdss_set_quirk(mdata, MDSS_QUIRK_NEED_SECURE_MAP);
break;
case MDSS_MDP_HW_REV_300:
@@ -4183,6 +4238,23 @@ static int mdss_mdp_parse_dt_bus_scale(struct platform_device *pdev)
pr_debug("mdss-reg-bus not found\n");
}
+ node = of_get_child_by_name(pdev->dev.of_node, "qcom,mdss-hw-rt-bus");
+ if (node) {
+ mdata->hw_rt_bus_scale_table =
+ msm_bus_pdata_from_node(pdev, node);
+ if (IS_ERR_OR_NULL(mdata->hw_rt_bus_scale_table)) {
+ rc = PTR_ERR(mdata->hw_rt_bus_scale_table);
+ if (!rc)
+ pr_err("hw_rt_bus_scale failed rc=%d\n", rc);
+ rc = 0;
+ mdata->hw_rt_bus_scale_table = NULL;
+ }
+ } else {
+ rc = 0;
+ mdata->hw_rt_bus_scale_table = NULL;
+ pr_debug("mdss-hw-rt-bus not found\n");
+ }
+
return rc;
}
#else
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index f5413b73f27d..6b71931cb582 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1161,7 +1161,7 @@ int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe,
prefill_params.is_hflip = pipe->flags & MDP_FLIP_LR;
prefill_params.is_cmd = !mixer->ctl->is_video_mode;
prefill_params.pnum = pipe->num;
- prefill_params.is_bwc = mdss_mdp_is_ubwc_format(pipe->src_fmt);
+ prefill_params.is_ubwc = mdss_mdp_is_ubwc_format(pipe->src_fmt);
prefill_params.is_nv12 = mdss_mdp_is_nv12_format(pipe->src_fmt);
mdss_mdp_get_bw_vote_mode(mixer, mdata->mdp_rev, perf,
@@ -4276,16 +4276,16 @@ void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl,
}
previous_frame_pu_type = mdss_mdp_get_pu_type(ctl);
- mdss_mdp_set_mixer_roi(ctl->mixer_left, l_roi);
- if (ctl->mixer_left)
+ if (ctl->mixer_left) {
+ mdss_mdp_set_mixer_roi(ctl->mixer_left, l_roi);
ctl->roi = ctl->mixer_left->roi;
+ }
if (ctl->mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY) {
struct mdss_mdp_ctl *sctl = mdss_mdp_get_split_ctl(ctl);
- if (sctl) {
- mdss_mdp_set_mixer_roi(sctl->mixer_left, r_roi);
- if (sctl->mixer_left)
+ if (sctl && sctl->mixer_left) {
+ mdss_mdp_set_mixer_roi(sctl->mixer_left, r_roi);
sctl->roi = sctl->mixer_left->roi;
}
} else if (is_dual_lm_single_display(ctl->mfd) && ctl->mixer_right) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_layer.c b/drivers/video/msm/mdss/mdss_mdp_layer.c
index 8d0167a94837..cd95c3c9de9b 100644
--- a/drivers/video/msm/mdss/mdss_mdp_layer.c
+++ b/drivers/video/msm/mdss/mdss_mdp_layer.c
@@ -345,7 +345,7 @@ static int __validate_layer_reconfig(struct mdp_input_layer *layer,
*/
if (pipe->csc_coeff_set != layer->color_space) {
src_fmt = mdss_mdp_get_format_params(layer->buffer.format);
- if (pipe->src_fmt->is_yuv && src_fmt->is_yuv) {
+ if (pipe->src_fmt->is_yuv && src_fmt && src_fmt->is_yuv) {
status = -EPERM;
pr_err("csc change is not permitted on used pipe\n");
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 12779107632a..081f1bd0a24b 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -3365,18 +3365,20 @@ static ssize_t mdss_mdp_misr_store(struct device *dev,
req.frame_count = 1;
} else {
pr_err("misr not supported fo this fb:%d\n", mfd->index);
+ rc = -ENODEV;
+ return rc;
}
if (enable_misr) {
mdss_misr_set(mdata, &req , ctl);
- if (is_panel_split(mfd))
+ if ((ctl->intf_type == MDSS_INTF_DSI) && is_panel_split(mfd))
mdss_misr_set(mdata, &sreq , ctl);
} else {
mdss_misr_disable(mdata, &req, ctl);
- if (is_panel_split(mfd))
+ if ((ctl->intf_type == MDSS_INTF_DSI) && is_panel_split(mfd))
mdss_misr_disable(mdata, &sreq , ctl);
}
@@ -4824,6 +4826,7 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
int rc;
struct mdss_overlay_private *mdp5_data;
struct mdss_mdp_ctl *ctl = NULL;
+ struct mdss_data_type *mdata;
if (!mfd)
return -ENODEV;
@@ -4835,6 +4838,10 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
if (!mdp5_data)
return -EINVAL;
+ mdata = mfd_to_mdata(mfd);
+ if (!mdata)
+ return -EINVAL;
+
mdss_mdp_set_lm_flag(mfd);
if (!mdp5_data->ctl) {
@@ -4864,9 +4871,16 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
if (rc)
goto panel_on;
+ /* Skip the overlay start and kickoff for all displays
+ if handoff is pending. Previously we skipped it for DTV
+ panel and pluggable panels (bridge chip hdmi case). But
+ it does not cover the case where there is a non pluggable
+ tertiary display. Using the flag handoff_pending to skip
+ overlay start and kickoff should cover all cases
+ TODO: In the long run, the overlay start and kickoff
+ should not be skipped, instead, the handoff can be done */
if (!mfd->panel_info->cont_splash_enabled &&
- (mfd->panel_info->type != DTV_PANEL) &&
- !mfd->panel_info->is_pluggable) {
+ !mdata->handoff_pending) {
rc = mdss_mdp_overlay_start(mfd);
if (rc)
goto end;
diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
index bd9b44ff2a9c..c97c946ae2f1 100644
--- a/drivers/video/msm/mdss/mdss_panel.h
+++ b/drivers/video/msm/mdss/mdss_panel.h
@@ -606,6 +606,7 @@ struct mdss_panel_info {
bool ulps_suspend_enabled;
bool panel_ack_disabled;
bool esd_check_enabled;
+ bool allow_phy_power_off;
char dfps_update;
/* new requested fps before it is updated in hw */
int new_fps;
diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c
index 502e0069d880..722460a6693e 100644
--- a/drivers/video/msm/mdss/msm_mdss_io_8974.c
+++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c
@@ -1847,7 +1847,11 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle,
{
int rc = 0;
struct mdss_dsi_ctrl_pdata *mctrl = NULL;
- int i;
+ int i, *vote_cnt;
+
+ void *m_clk_handle;
+ bool is_ecg = false;
+ int state = MDSS_DSI_CLK_OFF;
if (!ctrl) {
pr_err("%s: Invalid arg\n", __func__);
@@ -1879,6 +1883,18 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle,
}
/*
+ * it should add and remove extra votes based on voting clients to avoid
+ * removal of legitimate vote from DSI client.
+ */
+ if (mctrl && (clk_handle == ctrl->dsi_clk_handle)) {
+ m_clk_handle = mctrl->dsi_clk_handle;
+ vote_cnt = &mctrl->m_dsi_vote_cnt;
+ } else if (mctrl) {
+ m_clk_handle = mctrl->mdp_clk_handle;
+ vote_cnt = &mctrl->m_mdp_vote_cnt;
+ }
+
+ /*
* When DSI is used in split mode, the link clock for master controller
* has to be turned on first before the link clock for slave can be
* turned on. In case the current controller is a slave, an ON vote is
@@ -1890,18 +1906,24 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle,
__func__, ctrl->ndx, clk_type, clk_state,
__builtin_return_address(0), mctrl ? 1 : 0);
if (mctrl && (clk_type & MDSS_DSI_LINK_CLK)) {
- rc = mdss_dsi_clk_req_state(mctrl->dsi_clk_handle,
- MDSS_DSI_ALL_CLKS,
- MDSS_DSI_CLK_ON);
+ if (clk_state != MDSS_DSI_CLK_ON) {
+ /* preserve clk state; do not turn off forcefully */
+ is_ecg = is_dsi_clk_in_ecg_state(m_clk_handle);
+ if (is_ecg)
+ state = MDSS_DSI_CLK_EARLY_GATE;
+ }
+
+ rc = mdss_dsi_clk_req_state(m_clk_handle,
+ MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON, mctrl->ndx);
if (rc) {
pr_err("%s: failed to turn on mctrl clocks, rc=%d\n",
__func__, rc);
goto error;
}
- ctrl->m_vote_cnt++;
+ (*vote_cnt)++;
}
- rc = mdss_dsi_clk_req_state(clk_handle, clk_type, clk_state);
+ rc = mdss_dsi_clk_req_state(clk_handle, clk_type, clk_state, ctrl->ndx);
if (rc) {
pr_err("%s: failed set clk state, rc = %d\n", __func__, rc);
goto error;
@@ -1930,24 +1952,24 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle,
* for ON, since the previous ECG state must have
* removed two votes to let clocks turn off.
*
- * To satisfy the above requirement, m_vote_cnt keeps track of
+ * To satisfy the above requirement, vote_cnt keeps track of
* the number of ON votes for master requested by slave. For
- * every OFF/ECG state request, Either 2 or m_vote_cnt number of
+ * every OFF/ECG state request, Either 2 or vote_cnt number of
* votes are removed depending on which is lower.
*/
- for (i = 0; (i < ctrl->m_vote_cnt && i < 2); i++) {
- rc = mdss_dsi_clk_req_state(mctrl->dsi_clk_handle,
- MDSS_DSI_ALL_CLKS,
- MDSS_DSI_CLK_OFF);
+ for (i = 0; (i < *vote_cnt && i < 2); i++) {
+ rc = mdss_dsi_clk_req_state(m_clk_handle,
+ MDSS_DSI_ALL_CLKS, state, mctrl->ndx);
if (rc) {
pr_err("%s: failed to set mctrl clk state, rc = %d\n",
__func__, rc);
goto error;
}
}
- ctrl->m_vote_cnt -= i;
- pr_debug("%s: ctrl=%d, m_vote_cnt=%d\n", __func__, ctrl->ndx,
- ctrl->m_vote_cnt);
+ (*vote_cnt) -= i;
+ pr_debug("%s: ctrl=%d, vote_cnt=%d dsi_vote_cnt=%d mdp_vote_cnt:%d\n",
+ __func__, ctrl->ndx, *vote_cnt, mctrl->m_dsi_vote_cnt,
+ mctrl->m_mdp_vote_cnt);
}
error:
diff --git a/drivers/video/msm/msm_dba/adv7533.c b/drivers/video/msm/msm_dba/adv7533.c
index a3b4466d105d..8503d84e0de4 100644
--- a/drivers/video/msm/msm_dba/adv7533.c
+++ b/drivers/video/msm/msm_dba/adv7533.c
@@ -880,8 +880,8 @@ static void adv7533_handle_cec_intr(struct adv7533 *pdata, u8 cec_status)
{
u8 cec_int_clear = 0x08;
bool cec_rx_intr = false;
- u8 cec_rx_ready;
- u8 cec_rx_timestamp;
+ u8 cec_rx_ready = 0;
+ u8 cec_rx_timestamp = 0;
if (!pdata) {
pr_err("%s: Invalid input\n", __func__);
@@ -983,7 +983,7 @@ end:
static void *adv7533_handle_hpd_intr(struct adv7533 *pdata)
{
- int ret;
+ int ret = 0;
u8 hpd_state;
u8 connected = 0, disconnected = 0;
diff --git a/include/dt-bindings/clock/msm-clocks-8996.h b/include/dt-bindings/clock/msm-clocks-8996.h
index 82ca331c7057..9a0fc514ce68 100644
--- a/include/dt-bindings/clock/msm-clocks-8996.h
+++ b/include/dt-bindings/clock/msm-clocks-8996.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -542,4 +542,5 @@
#define clk_audio_ap_clk 0x312ac429
#define clk_audio_pmi_clk 0xb7ba2274
#define clk_audio_ap_clk2 0xf0fbaf5b
+#define clk_audio_lpass_mclk2 0x0122abee
#endif
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 3b25d7d1280c..768c44d9ea8b 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -144,10 +144,10 @@ the appropriate macros. */
/* This needs to be modified manually now, when we add
a new RANGE of SSIDs to the msg_mask_tbl */
#define MSG_MASK_TBL_CNT 25
-#define APPS_EVENT_LAST_ID 0x0ABB
+#define APPS_EVENT_LAST_ID 0x0B14
#define MSG_SSID_0 0
-#define MSG_SSID_0_LAST 117
+#define MSG_SSID_0_LAST 118
#define MSG_SSID_1 500
#define MSG_SSID_1_LAST 506
#define MSG_SSID_2 1000
@@ -335,7 +335,8 @@ static const uint32_t msg_bld_masks_0[] = {
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
MSG_LVL_MED,
- MSG_LVL_MED
+ MSG_LVL_MED,
+ MSG_LVL_HIGH
};
static const uint32_t msg_bld_masks_1[] = {
@@ -853,7 +854,7 @@ static const uint32_t msg_bld_masks_23[] = {
/* LOG CODES */
static const uint32_t log_code_last_tbl[] = {
0x0, /* EQUIP ID 0 */
- 0x192C, /* EQUIP ID 1 */
+ 0x1966, /* EQUIP ID 1 */
0x0, /* EQUIP ID 2 */
0x0, /* EQUIP ID 3 */
0x4910, /* EQUIP ID 4 */
diff --git a/include/linux/ipa.h b/include/linux/ipa.h
index 3a87177b623f..0dd2f0bf9c23 100644
--- a/include/linux/ipa.h
+++ b/include/linux/ipa.h
@@ -524,7 +524,11 @@ struct ipa_ext_intf {
* in system-BAM mode
* @ipa_ep_cfg: IPA EP configuration
* @client: the type of client who "owns" the EP
- * @desc_fifo_sz: size of desc FIFO
+ * @desc_fifo_sz: size of desc FIFO. This number is used to allocate the desc
+ * fifo for BAM. For GSI, this size is used by IPA driver as a
+ * baseline to calculate the GSI ring size in the following way:
+ * For PROD pipes, GSI ring is 4 * desc_fifo_sz.
+ For PROD pipes, GSI ring is 2 * desc_fifo_sz.
* @priv: callback cookie
* @notify: callback
* priv - callback cookie
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 5cd72b06bec7..7bebacaee0ac 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -75,8 +75,8 @@ int memblock_reserve(phys_addr_t base, phys_addr_t size);
void memblock_trim_memory(phys_addr_t align);
int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);
int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
-void memblock_region_resize_late_begin(void);
-void memblock_region_resize_late_end(void);
+unsigned long memblock_region_resize_late_begin(void);
+void memblock_region_resize_late_end(unsigned long);
/* Low level functions */
int memblock_add_range(struct memblock_type *type,
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index 138aeca4f7fb..65dbdd7756e2 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -74,6 +74,7 @@ struct msm_thermal_data {
int32_t cx_phase_request_key;
int32_t vdd_mx_temp_degC;
int32_t vdd_mx_temp_hyst_degC;
+ int32_t vdd_mx_sensor_id;
int32_t therm_reset_temp_degC;
};
@@ -91,6 +92,7 @@ struct therm_threshold {
int32_t trip_triggered;
void (*notify)(struct therm_threshold *);
struct threshold_info *parent;
+ int32_t cur_state;
};
struct threshold_info {
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 705ac2f7181c..d10a4e1dd1b0 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -208,6 +208,7 @@ enum power_supply_property {
POWER_SUPPLY_PROP_RESTRICTED_CHARGING,
POWER_SUPPLY_PROP_CURRENT_CAPABILITY,
POWER_SUPPLY_PROP_TYPEC_MODE,
+ POWER_SUPPLY_PROP_ALLOW_HVDCP3,
/* Local extensions of type int64_t */
POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT,
/* Properties of type `const char *' */
diff --git a/include/linux/qdsp6v2/apr_tal.h b/include/linux/qdsp6v2/apr_tal.h
index eeb6ede976ad..ee8b2f5a8b5b 100644
--- a/include/linux/qdsp6v2/apr_tal.h
+++ b/include/linux/qdsp6v2/apr_tal.h
@@ -87,6 +87,7 @@ struct apr_svc_ch_dev {
wait_queue_head_t wait;
void *priv;
unsigned channel_state;
+ bool if_remote_intent_ready;
};
#else
struct apr_svc_ch_dev {
diff --git a/include/linux/sched.h b/include/linux/sched.h
index cfe267dfde27..2db6efb4a19f 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1324,6 +1324,7 @@ struct task_struct {
u32 init_load_pct;
u64 last_wake_ts;
u64 last_switch_out_ts;
+ u64 last_cpu_selected_ts;
#ifdef CONFIG_SCHED_QHMP
u64 run_start;
#endif
diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h
index 719a40be8cf1..35b07496dd44 100644
--- a/include/linux/sched/sysctl.h
+++ b/include/linux/sched/sysctl.h
@@ -69,6 +69,7 @@ extern unsigned int sysctl_sched_boost;
extern unsigned int sysctl_early_detection_duration;
extern unsigned int sysctl_sched_small_wakee_task_load_pct;
extern unsigned int sysctl_sched_big_waker_task_load_pct;
+extern unsigned int sysctl_sched_prefer_sync_wakee_to_waker;
#ifdef CONFIG_SCHED_QHMP
extern unsigned int sysctl_sched_min_runtime;
diff --git a/include/linux/soundwire/soundwire.h b/include/linux/soundwire/soundwire.h
index f19e871d6ac2..4b957245209e 100644
--- a/include/linux/soundwire/soundwire.h
+++ b/include/linux/soundwire/soundwire.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -151,6 +151,7 @@ struct swr_master {
const void *buf, size_t len);
int (*get_logical_dev_num)(struct swr_master *mstr, u64 dev_id,
u8 *dev_num);
+ void (*slvdev_datapath_control)(struct swr_master *mstr, bool enable);
};
static inline struct swr_master *to_swr_master(struct device *dev)
@@ -304,4 +305,6 @@ extern int swr_device_down(struct swr_device *swr_dev);
extern int swr_reset_device(struct swr_device *swr_dev);
+extern int swr_slvdev_datapath_control(struct swr_device *swr_dev, u8 dev_num,
+ bool enable);
#endif /* _LINUX_SOUNDWIRE_H */
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index c42bd0a6b34a..9a30c1e01fb2 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -235,6 +235,8 @@ struct hc_driver {
#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
#define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */
#define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */
+#define HCD_RT_OLD_ENUM 0x0008 /* HC supports short enumeration
+ on root port */
#define HCD_USB11 0x0010 /* USB 1.1 */
#define HCD_USB2 0x0020 /* USB 2.0 */
#define HCD_USB25 0x0030 /* Wireless USB 1.0 (USB 2.5)*/
@@ -381,6 +383,7 @@ struct hc_driver {
int (*disable_usb3_lpm_timeout)(struct usb_hcd *,
struct usb_device *, enum usb3_link_state state);
int (*find_raw_port_number)(struct usb_hcd *, int);
+ void (*log_urb)(struct urb *urb, char *event, unsigned extra);
void (*dump_regs)(struct usb_hcd *);
void (*set_autosuspend_delay)(struct usb_device *);
void (*reset_sof_bug_handler)(struct usb_hcd *hcd, u32 val);
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 939d06688928..d32fffd40b90 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -599,6 +599,8 @@ struct msm_hsic_host_platform_data {
/* gpio used to resume peripheral */
unsigned resume_gpio;
+ int *tlmm_init_seq;
+ int tlmm_seq_count;
/*swfi latency is required while driving resume on to the bus */
u32 swfi_latency;
diff --git a/include/net/cnss.h b/include/net/cnss.h
index e9d0ca85d7f2..b37bbab30579 100644
--- a/include/net/cnss.h
+++ b/include/net/cnss.h
@@ -16,9 +16,7 @@
#include <linux/skbuff.h>
#include <linux/pci.h>
#include <net/cnss_common.h>
-#ifdef CONFIG_CNSS_SDIO
#include <linux/mmc/sdio_func.h>
-#endif
#ifdef CONFIG_CNSS
#define CNSS_MAX_FILE_NAME 20
@@ -189,7 +187,6 @@ enum {
};
extern int cnss_get_restart_level(void);
-#ifdef CONFIG_CNSS_SDIO
struct cnss_sdio_wlan_driver {
const char *name;
const struct sdio_device_id *id_table;
@@ -212,5 +209,4 @@ extern int cnss_wlan_query_oob_status(void);
extern int cnss_wlan_register_oob_irq_handler(oob_irq_handler_t handler,
void *pm_oob);
extern int cnss_wlan_unregister_oob_irq_handler(void *pm_oob);
-#endif
#endif /* _NET_CNSS_H_ */
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 5bffd4f1ac68..d2cf8c2973d3 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -2,6 +2,7 @@
* Video for Linux Two header file
*
* Copyright (C) 1999-2012 the contributors
+ * Copyright (c) 2016, 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 as published by
@@ -410,6 +411,12 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8')
#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8')
+ /* 10bit raw bayer DPCM compressed to 6 bits */
+#define V4L2_PIX_FMT_SBGGR10DPCM6 v4l2_fourcc('b', 'B', 'A', '6')
+#define V4L2_PIX_FMT_SGBRG10DPCM6 v4l2_fourcc('b', 'G', 'A', '6')
+#define V4L2_PIX_FMT_SGRBG10DPCM6 v4l2_fourcc('B', 'D', '1', '6')
+#define V4L2_PIX_FMT_SRGGB10DPCM6 v4l2_fourcc('b', 'R', 'A', '6')
+
/*
* 10bit raw bayer, expanded to 16 bits
* xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
@@ -1893,12 +1900,19 @@ struct v4l2_streamparm {
#define V4L2_EVENT_MOTION_DET 6
#define V4L2_EVENT_PRIVATE_START 0x08000000
+#define V4L2_EVENT_BITDEPTH_FLAG 0x1
+#define V4L2_EVENT_PICSTRUCT_FLAG 0x2
+
#define V4L2_EVENT_MSM_VIDC_START (V4L2_EVENT_PRIVATE_START + 0x00001000)
#define V4L2_EVENT_MSM_VIDC_FLUSH_DONE (V4L2_EVENT_MSM_VIDC_START + 1)
#define V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT \
(V4L2_EVENT_MSM_VIDC_START + 2)
#define V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT \
(V4L2_EVENT_MSM_VIDC_START + 3)
+/*
+ * Bitdepth changed insufficient is deprecated now, however retaining
+ * to prevent changing the values of the other macros after bitdepth
+ */
#define V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT \
(V4L2_EVENT_MSM_VIDC_START + 4)
#define V4L2_EVENT_MSM_VIDC_SYS_ERROR (V4L2_EVENT_MSM_VIDC_START + 5)
diff --git a/include/uapi/media/msm_camsensor_sdk.h b/include/uapi/media/msm_camsensor_sdk.h
index 3985e9750af7..01e52b6f7b44 100644
--- a/include/uapi/media/msm_camsensor_sdk.h
+++ b/include/uapi/media/msm_camsensor_sdk.h
@@ -18,6 +18,7 @@
#define CSI_DECODE_8BIT 1
#define CSI_DECODE_10BIT 2
#define CSI_DECODE_12BIT 3
+#define CSI_DECODE_DPCM_10_6_10 4
#define CSI_DECODE_DPCM_10_8_10 5
#define MAX_CID 16
#define I2C_SEQ_REG_DATA_MAX 1024
diff --git a/include/uapi/media/msm_vidc.h b/include/uapi/media/msm_vidc.h
index ac36b23bfa97..eaf2f5e02d0e 100644
--- a/include/uapi/media/msm_vidc.h
+++ b/include/uapi/media/msm_vidc.h
@@ -225,4 +225,9 @@ enum msm_vidc_pixel_depth {
MSM_VIDC_BIT_DEPTH_10,
MSM_VIDC_BIT_DEPTH_UNSUPPORTED = 0XFFFFFFFF,
};
+
+/*enum msm_vidc_pic_struct */
+#define MSM_VIDC_PIC_STRUCT_MAYBE_INTERLACED 0x0
+#define MSM_VIDC_PIC_STRUCT_PROGRESSIVE 0x1
+
#endif
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 96e250d87936..a19ca1b74160 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -512,7 +512,6 @@ void pm_qos_add_request(struct pm_qos_request *req,
#ifdef CONFIG_SMP
case PM_QOS_REQ_AFFINE_IRQ:
if (irq_can_set_affinity(req->irq)) {
- int ret = 0;
struct irq_desc *desc = irq_to_desc(req->irq);
struct cpumask *mask = desc->irq_data.affinity;
@@ -522,13 +521,6 @@ void pm_qos_add_request(struct pm_qos_request *req,
req->irq_notify.notify = pm_qos_irq_notify;
req->irq_notify.release = pm_qos_irq_release;
- ret = irq_set_affinity_notifier(req->irq,
- &req->irq_notify);
- if (ret) {
- WARN(1, KERN_ERR "IRQ affinity notify set failed\n");
- req->type = PM_QOS_REQ_ALL_CORES;
- cpumask_setall(&req->cpus_affine);
- }
} else {
req->type = PM_QOS_REQ_ALL_CORES;
cpumask_setall(&req->cpus_affine);
@@ -550,6 +542,24 @@ void pm_qos_add_request(struct pm_qos_request *req,
trace_pm_qos_add_request(pm_qos_class, value);
pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints,
req, PM_QOS_ADD_REQ, value);
+
+#ifdef CONFIG_SMP
+ if (req->type == PM_QOS_REQ_AFFINE_IRQ &&
+ irq_can_set_affinity(req->irq)) {
+ int ret = 0;
+
+ ret = irq_set_affinity_notifier(req->irq,
+ &req->irq_notify);
+ if (ret) {
+ WARN(1, "IRQ affinity notify set failed\n");
+ req->type = PM_QOS_REQ_ALL_CORES;
+ cpumask_setall(&req->cpus_affine);
+ pm_qos_update_target(
+ pm_qos_array[pm_qos_class]->constraints,
+ req, PM_QOS_UPDATE_REQ, value);
+ }
+ }
+#endif
}
EXPORT_SYMBOL_GPL(pm_qos_add_request);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 7ccf09ac095a..c61bd0932136 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2822,6 +2822,7 @@ static inline void mark_task_starting(struct task_struct *p)
wallclock = sched_ktime_clock();
p->ravg.mark_start = p->last_wake_ts = wallclock;
+ p->last_cpu_selected_ts = wallclock;
p->last_switch_out_ts = 0;
}
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 0f30df8f25af..8214707009fd 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2480,6 +2480,13 @@ unsigned int __read_mostly sched_big_waker_task_load;
unsigned int __read_mostly sysctl_sched_big_waker_task_load_pct = 25;
/*
+ * Prefer the waker CPU for sync wakee task, if the CPU has only 1 runnable
+ * task. This eliminates the LPM exit latency associated with the idle
+ * CPUs in the waker cluster.
+ */
+unsigned int __read_mostly sysctl_sched_prefer_sync_wakee_to_waker;
+
+/*
* CPUs with load greater than the sched_spill_load_threshold are not
* eligible for task placement. When all CPUs in a cluster achieve a
* load higher than this level, tasks becomes eligible for inter
@@ -2548,6 +2555,9 @@ static unsigned int __read_mostly
sched_short_sleep_task_threshold = 2000 * NSEC_PER_USEC;
unsigned int __read_mostly sysctl_sched_select_prev_cpu_us = 2000;
+static unsigned int __read_mostly
+sched_long_cpu_selection_threshold = 100 * NSEC_PER_MSEC;
+
unsigned int __read_mostly sysctl_sched_restrict_cluster_spill;
void update_up_down_migrate(void)
@@ -3239,6 +3249,7 @@ bias_to_prev_cpu(struct cpu_select_env *env, struct cluster_cpu_stats *stats)
struct sched_cluster *cluster;
if (env->boost || env->reason || env->need_idle ||
+ !task->ravg.mark_start ||
!sched_short_sleep_task_threshold)
return false;
@@ -3247,6 +3258,10 @@ bias_to_prev_cpu(struct cpu_select_env *env, struct cluster_cpu_stats *stats)
unlikely(!cpu_active(prev_cpu)))
return false;
+ if (task->ravg.mark_start - task->last_cpu_selected_ts >=
+ sched_long_cpu_selection_threshold)
+ return false;
+
/*
* This function should be used by task wake up path only as it's
* assuming p->last_switch_out_ts as last sleep time.
@@ -3307,6 +3322,7 @@ static int select_best_cpu(struct task_struct *p, int target, int reason,
struct cluster_cpu_stats stats;
bool fast_path = false;
struct related_thread_group *grp;
+ int cpu = raw_smp_processor_id();
struct cpu_select_env env = {
.p = p,
@@ -3345,12 +3361,20 @@ static int select_best_cpu(struct task_struct *p, int target, int reason,
else
env.rtg = grp;
} else {
- cluster = cpu_rq(smp_processor_id())->cluster;
- if (wake_to_waker_cluster(&env) &&
- cluster_allowed(p, cluster)) {
- env.need_waker_cluster = 1;
- bitmap_zero(env.candidate_list, NR_CPUS);
- __set_bit(cluster->id, env.candidate_list);
+ cluster = cpu_rq(cpu)->cluster;
+ if (wake_to_waker_cluster(&env)) {
+ if (sysctl_sched_prefer_sync_wakee_to_waker &&
+ cpu_rq(cpu)->nr_running == 1 &&
+ cpumask_test_cpu(cpu, tsk_cpus_allowed(p)) &&
+ cpu_active(cpu)) {
+ fast_path = true;
+ target = cpu;
+ goto out;
+ } else if (cluster_allowed(p, cluster)) {
+ env.need_waker_cluster = 1;
+ bitmap_zero(env.candidate_list, NR_CPUS);
+ __set_bit(cluster->id, env.candidate_list);
+ }
} else if (bias_to_prev_cpu(&env, &stats)) {
fast_path = true;
goto out;
@@ -3393,6 +3417,7 @@ retry:
if (stats.best_capacity_cpu >= 0)
target = stats.best_capacity_cpu;
}
+ p->last_cpu_selected_ts = sched_ktime_clock();
out:
rcu_read_unlock();
@@ -4784,17 +4809,25 @@ static void check_enqueue_throttle(struct cfs_rq *cfs_rq);
static void
enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
{
+ bool renorm = !(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_WAKING);
+ bool curr = cfs_rq->curr == se;
+
/*
- * Update the normalized vruntime before updating min_vruntime
- * through calling update_curr().
+ * If we're the current task, we must renormalise before calling
+ * update_curr().
*/
- if (!(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_WAKING))
+ if (renorm && curr)
se->vruntime += cfs_rq->min_vruntime;
+ update_curr(cfs_rq);
+
/*
- * Update run-time statistics of the 'current'.
+ * Otherwise, renormalise after, such that we're placed at the current
+ * moment in time, instead of some random moment in the past.
*/
- update_curr(cfs_rq);
+ if (renorm && !curr)
+ se->vruntime += cfs_rq->min_vruntime;
+
enqueue_entity_load_avg(cfs_rq, se, flags & ENQUEUE_WAKEUP);
account_entity_enqueue(cfs_rq, se);
update_cfs_shares(cfs_rq);
@@ -4806,7 +4839,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
update_stats_enqueue(cfs_rq, se, !!(flags & ENQUEUE_MIGRATING));
check_spread(cfs_rq, se);
- if (se != cfs_rq->curr)
+ if (!curr)
__enqueue_entity(cfs_rq, se);
se->on_rq = 1;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 4fa328e14820..3065771d7971 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -481,6 +481,15 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
+ {
+ .procname = "sched_prefer_sync_wakee_to_waker",
+ .data = &sysctl_sched_prefer_sync_wakee_to_waker,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &one,
+ },
#ifdef CONFIG_SCHED_FREQ_INPUT
{
.procname = "sched_new_task_windows",
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
index 0f5df4abc4bf..17b5a671cf44 100644
--- a/kernel/trace/trace_event_perf.c
+++ b/kernel/trace/trace_event_perf.c
@@ -256,10 +256,8 @@ int perf_trace_add(struct perf_event *p_event, int flags)
void perf_trace_del(struct perf_event *p_event, int flags)
{
struct ftrace_event_call *tp_event = p_event->tp_event;
- if(!hlist_unhashed(&p_event->hlist_entry))
+ if (!hlist_unhashed(&p_event->hlist_entry))
hlist_del_rcu(&p_event->hlist_entry);
- else
- return;
tp_event->class->reg(tp_event, TRACE_REG_PERF_DEL, p_event);
}
diff --git a/mm/memblock.c b/mm/memblock.c
index eb9667374e04..eb096ebc475e 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -21,6 +21,7 @@
#include <linux/memblock.h>
#include <linux/preempt.h>
#include <linux/seqlock.h>
+#include <linux/irqflags.h>
#include <asm-generic/sections.h>
#include <linux/io.h>
@@ -1557,30 +1558,35 @@ void __init memblock_allow_resize(void)
memblock_can_resize = 1;
}
-static void __init_memblock memblock_resize_late(int begin)
+static unsigned long __init_memblock
+memblock_resize_late(int begin, unsigned long flags)
{
static int memblock_can_resize_old;
if (begin) {
preempt_disable();
+ local_irq_save(flags);
memblock_can_resize_old = memblock_can_resize;
memblock_can_resize = 0;
raw_write_seqcount_begin(&memblock_seq);
} else {
raw_write_seqcount_end(&memblock_seq);
memblock_can_resize = memblock_can_resize_old;
+ local_irq_restore(flags);
preempt_enable();
}
+
+ return flags;
}
-void __init_memblock memblock_region_resize_late_begin(void)
+unsigned long __init_memblock memblock_region_resize_late_begin(void)
{
- memblock_resize_late(1);
+ return memblock_resize_late(1, 0);
}
-void __init_memblock memblock_region_resize_late_end(void)
+void __init_memblock memblock_region_resize_late_end(unsigned long flags)
{
- memblock_resize_late(0);
+ memblock_resize_late(0, flags);
}
static int __init early_memblock(char *p)
diff --git a/net/ipc_router/ipc_router_core.c b/net/ipc_router/ipc_router_core.c
index 46456684350c..4f1ce53f7efa 100644
--- a/net/ipc_router/ipc_router_core.c
+++ b/net/ipc_router/ipc_router_core.c
@@ -1923,11 +1923,6 @@ static int ipc_router_send_ctl_msg(
ret = process_resume_tx_msg(msg, pkt);
} else if (xprt_info && (msg->cmd == IPC_ROUTER_CTRL_CMD_HELLO ||
xprt_info->initialized)) {
- ret = ipc_router_get_xprt_info_ref(xprt_info);
- if (ret < 0) {
- IPC_RTR_ERR("%s: Abort invalid xprt\n", __func__);
- return ret;
- }
mutex_lock(&xprt_info->tx_lock_lhb2);
ipc_router_log_msg(xprt_info->log_ctx,
IPC_ROUTER_LOG_EVENT_TX, msg, hdr, NULL, NULL);
@@ -1936,14 +1931,11 @@ static int ipc_router_send_ctl_msg(
mutex_unlock(&xprt_info->tx_lock_lhb2);
IPC_RTR_ERR("%s: Prepend Header failed\n", __func__);
release_pkt(pkt);
- kref_put(&xprt_info->ref,
- ipc_router_release_xprt_info_ref);
return ret;
}
ret = xprt_info->xprt->write(pkt, pkt->length, xprt_info->xprt);
mutex_unlock(&xprt_info->tx_lock_lhb2);
- kref_put(&xprt_info->ref, ipc_router_release_xprt_info_ref);
}
release_pkt(pkt);
@@ -3254,9 +3246,16 @@ static int msm_ipc_router_send_resume_tx(void *data)
__func__, hdr->src_node_id);
return -ENODEV;
}
+ ret = ipc_router_get_xprt_info_ref(rt_entry->xprt_info);
+ if (ret < 0) {
+ IPC_RTR_ERR("%s: Abort invalid xprt\n", __func__);
+ kref_put(&rt_entry->ref, ipc_router_release_rtentry);
+ return ret;
+ }
ret = ipc_router_send_ctl_msg(rt_entry->xprt_info, &msg,
hdr->src_node_id);
kref_put(&rt_entry->ref, ipc_router_release_rtentry);
+ kref_put(&rt_entry->xprt_info->ref, ipc_router_release_xprt_info_ref);
if (ret < 0)
IPC_RTR_ERR(
"%s: Send Resume_Tx Failed SRC_NODE: %d SRC_PORT: %d DEST_NODE: %d",
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index 87603f69eabc..4b9095d337ba 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -1174,6 +1174,38 @@ static void iface_stat_update(struct net_device *net_dev, bool stash_only)
spin_unlock_bh(&iface_stat_list_lock);
}
+/* Guarantied to return a net_device that has a name */
+static void get_dev_and_dir(const struct sk_buff *skb,
+ struct xt_action_param *par,
+ enum ifs_tx_rx *direction,
+ const struct net_device **el_dev)
+{
+ BUG_ON(!direction || !el_dev);
+
+ if (par->in) {
+ *el_dev = par->in;
+ *direction = IFS_RX;
+ } else if (par->out) {
+ *el_dev = par->out;
+ *direction = IFS_TX;
+ } else {
+ pr_err("qtaguid[%d]: %s(): no par->in/out?!!\n",
+ par->hooknum, __func__);
+ BUG();
+ }
+ if (unlikely(!(*el_dev)->name)) {
+ pr_err("qtaguid[%d]: %s(): no dev->name?!!\n",
+ par->hooknum, __func__);
+ BUG();
+ }
+ if (skb->dev && *el_dev != skb->dev) {
+ MT_DEBUG("qtaguid[%d]: skb->dev=%p %s vs par->%s=%p %s\n",
+ par->hooknum, skb->dev, skb->dev->name,
+ *direction == IFS_RX ? "in" : "out", *el_dev,
+ (*el_dev)->name);
+ }
+}
+
/*
* Update stats for the specified interface from the skb.
* Do nothing if the entry
@@ -1185,50 +1217,27 @@ static void iface_stat_update_from_skb(const struct sk_buff *skb,
{
struct iface_stat *entry;
const struct net_device *el_dev;
- enum ifs_tx_rx direction = par->in ? IFS_RX : IFS_TX;
+ enum ifs_tx_rx direction;
int bytes = skb->len;
int proto;
- if (!skb->dev) {
- MT_DEBUG("qtaguid[%d]: no skb->dev\n", par->hooknum);
- el_dev = par->in ? : par->out;
- } else {
- const struct net_device *other_dev;
- el_dev = skb->dev;
- other_dev = par->in ? : par->out;
- if (el_dev != other_dev) {
- MT_DEBUG("qtaguid[%d]: skb->dev=%p %s vs "
- "par->(in/out)=%p %s\n",
- par->hooknum, el_dev, el_dev->name, other_dev,
- other_dev->name);
- }
- }
-
- if (unlikely(!el_dev)) {
- pr_err_ratelimited("qtaguid[%d]: %s(): no par->in/out?!!\n",
- par->hooknum, __func__);
- BUG();
- } else if (unlikely(!el_dev->name)) {
- pr_err_ratelimited("qtaguid[%d]: %s(): no dev->name?!!\n",
- par->hooknum, __func__);
- BUG();
- } else {
- proto = ipx_proto(skb, par);
- MT_DEBUG("qtaguid[%d]: dev name=%s type=%d fam=%d proto=%d\n",
- par->hooknum, el_dev->name, el_dev->type,
- par->family, proto);
- }
+ get_dev_and_dir(skb, par, &direction, &el_dev);
+ proto = ipx_proto(skb, par);
+ MT_DEBUG("qtaguid[%d]: iface_stat: %s(%s): "
+ "type=%d fam=%d proto=%d dir=%d\n",
+ par->hooknum, __func__, el_dev->name, el_dev->type,
+ par->family, proto, direction);
spin_lock_bh(&iface_stat_list_lock);
entry = get_iface_entry(el_dev->name);
if (entry == NULL) {
- IF_DEBUG("qtaguid: iface_stat: %s(%s): not tracked\n",
- __func__, el_dev->name);
+ IF_DEBUG("qtaguid[%d]: iface_stat: %s(%s): not tracked\n",
+ par->hooknum, __func__, el_dev->name);
spin_unlock_bh(&iface_stat_list_lock);
return;
}
- IF_DEBUG("qtaguid: %s(%s): entry=%p\n", __func__,
+ IF_DEBUG("qtaguid[%d]: %s(%s): entry=%p\n", par->hooknum, __func__,
el_dev->name, entry);
data_counters_update(&entry->totals_via_skb, 0, direction, proto,
@@ -1293,13 +1302,13 @@ static void if_tag_stat_update(const char *ifname, uid_t uid,
iface_entry = get_iface_entry(ifname);
if (!iface_entry) {
- pr_err_ratelimited("qtaguid: iface_stat: stat_update() "
+ pr_err_ratelimited("qtaguid: tag_stat: stat_update() "
"%s not found\n", ifname);
return;
}
/* It is ok to process data when an iface_entry is inactive */
- MT_DEBUG("qtaguid: iface_stat: stat_update() dev=%s entry=%p\n",
+ MT_DEBUG("qtaguid: tag_stat: stat_update() dev=%s entry=%p\n",
ifname, iface_entry);
/*
@@ -1316,7 +1325,7 @@ static void if_tag_stat_update(const char *ifname, uid_t uid,
tag = combine_atag_with_uid(acct_tag, uid);
uid_tag = make_tag_from_uid(uid);
}
- MT_DEBUG("qtaguid: iface_stat: stat_update(): "
+ MT_DEBUG("qtaguid: tag_stat: stat_update(): "
" looking for tag=0x%llx (uid=%u) in ife=%p\n",
tag, get_uid_from_tag(tag), iface_entry);
/* Loop over tag list under this interface for {acct_tag,uid_tag} */
@@ -1576,8 +1585,8 @@ static struct sock *qtaguid_find_sk(const struct sk_buff *skb,
struct sock *sk;
unsigned int hook_mask = (1 << par->hooknum);
- MT_DEBUG("qtaguid: find_sk(skb=%p) hooknum=%d family=%d\n", skb,
- par->hooknum, par->family);
+ MT_DEBUG("qtaguid[%d]: find_sk(skb=%p) family=%d\n",
+ par->hooknum, skb, par->family);
/*
* Let's not abuse the the xt_socket_get*_sk(), or else it will
@@ -1598,8 +1607,8 @@ static struct sock *qtaguid_find_sk(const struct sk_buff *skb,
}
if (sk) {
- MT_DEBUG("qtaguid: %p->sk_proto=%u "
- "->sk_state=%d\n", sk, sk->sk_protocol, sk->sk_state);
+ MT_DEBUG("qtaguid[%d]: %p->sk_proto=%u->sk_state=%d\n",
+ par->hooknum, sk, sk->sk_protocol, sk->sk_state);
/*
* When in TCP_TIME_WAIT the sk is not a "struct sock" but
* "struct inet_timewait_sock" which is missing fields.
@@ -1618,37 +1627,19 @@ static void account_for_uid(const struct sk_buff *skb,
struct xt_action_param *par)
{
const struct net_device *el_dev;
+ enum ifs_tx_rx direction;
+ int proto;
- if (!skb->dev) {
- MT_DEBUG("qtaguid[%d]: no skb->dev\n", par->hooknum);
- el_dev = par->in ? : par->out;
- } else {
- const struct net_device *other_dev;
- el_dev = skb->dev;
- other_dev = par->in ? : par->out;
- if (el_dev != other_dev) {
- MT_DEBUG("qtaguid[%d]: skb->dev=%p %s vs "
- "par->(in/out)=%p %s\n",
- par->hooknum, el_dev, el_dev->name, other_dev,
- other_dev->name);
- }
- }
-
- if (unlikely(!el_dev)) {
- pr_info("qtaguid[%d]: no par->in/out?!!\n", par->hooknum);
- } else if (unlikely(!el_dev->name)) {
- pr_info("qtaguid[%d]: no dev->name?!!\n", par->hooknum);
- } else {
- int proto = ipx_proto(skb, par);
- MT_DEBUG("qtaguid[%d]: dev name=%s type=%d fam=%d proto=%d\n",
- par->hooknum, el_dev->name, el_dev->type,
- par->family, proto);
+ get_dev_and_dir(skb, par, &direction, &el_dev);
+ proto = ipx_proto(skb, par);
+ MT_DEBUG("qtaguid[%d]: dev name=%s type=%d fam=%d proto=%d dir=%d\n",
+ par->hooknum, el_dev->name, el_dev->type,
+ par->family, proto, direction);
- if_tag_stat_update(el_dev->name, uid,
- skb->sk ? skb->sk : alternate_sk,
- par->in ? IFS_RX : IFS_TX,
- proto, skb->len);
- }
+ if_tag_stat_update(el_dev->name, uid,
+ skb->sk ? skb->sk : alternate_sk,
+ direction,
+ proto, skb->len);
}
static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
@@ -1660,6 +1651,11 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
kuid_t sock_uid;
bool res;
bool set_sk_callback_lock = false;
+ /*
+ * TODO: unhack how to force just accounting.
+ * For now we only do tag stats when the uid-owner is not requested
+ */
+ bool do_tag_stat = !(info->match & XT_QTAGUID_UID);
if (unlikely(module_passive))
return (info->match ^ info->invert) == 0;
@@ -1733,12 +1729,7 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
* couldn't find the owner, so for now we just count them
* against the system.
*/
- /*
- * TODO: unhack how to force just accounting.
- * For now we only do iface stats when the uid-owner is not
- * requested.
- */
- if (!(info->match & XT_QTAGUID_UID))
+ if (do_tag_stat)
account_for_uid(skb, sk, 0, par);
MT_DEBUG("qtaguid[%d]: leaving (sk?sk->sk_socket)=%p\n",
par->hooknum,
@@ -1753,18 +1744,15 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
filp = sk->sk_socket->file;
if (filp == NULL) {
MT_DEBUG("qtaguid[%d]: leaving filp=NULL\n", par->hooknum);
- account_for_uid(skb, sk, 0, par);
+ if (do_tag_stat)
+ account_for_uid(skb, sk, 0, par);
res = ((info->match ^ info->invert) &
(XT_QTAGUID_UID | XT_QTAGUID_GID)) == 0;
atomic64_inc(&qtu_events.match_no_sk_file);
goto put_sock_ret_res;
}
sock_uid = filp->f_cred->fsuid;
- /*
- * TODO: unhack how to force just accounting.
- * For now we only do iface stats when the uid-owner is not requested
- */
- if (!(info->match & XT_QTAGUID_UID))
+ if (do_tag_stat)
account_for_uid(skb, sk, from_kuid(&init_user_ns, sock_uid), par);
/*
diff --git a/net/rmnet_data/rmnet_data_handlers.c b/net/rmnet_data/rmnet_data_handlers.c
index 6c40f229d5d6..9d04b2f8ddd9 100644
--- a/net/rmnet_data/rmnet_data_handlers.c
+++ b/net/rmnet_data/rmnet_data_handlers.c
@@ -516,10 +516,8 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
rmnet_stats_ul_checksum(ckresult);
}
- if (((config->egress_data_format &
- RMNET_EGRESS_FORMAT_MAP_CKSUMV4) &&
- (!(config->egress_data_format &
- RMNET_EGRESS_FORMAT_AGGREGATION))) ||
+ if ((!(config->egress_data_format &
+ RMNET_EGRESS_FORMAT_AGGREGATION)) ||
((orig_dev->features & NETIF_F_GSO) && skb_is_nonlinear(skb)))
map_header = rmnet_map_add_map_header
(skb, additional_header_length, RMNET_MAP_NO_PAD_BYTES);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index c3ecf366a27a..4fa9d4aa9456 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1747,22 +1747,14 @@ __reg_process_hint_driver(struct regulatory_request *driver_request)
{
struct regulatory_request *lr = get_last_request();
- if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) {
- if (regdom_changes(driver_request->alpha2))
- return REG_REQ_OK;
+ if (!regdom_changes(driver_request->alpha2))
return REG_REQ_ALREADY_SET;
- }
- /*
- * This would happen if you unplug and plug your card
- * back in or if you add a new device for which the previously
- * loaded card also agrees on the regulatory domain.
- */
- if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
- !regdom_changes(driver_request->alpha2))
- return REG_REQ_ALREADY_SET;
+ if (lr->initiator == NL80211_REGDOM_SET_BY_USER)
+ return REG_REQ_INTERSECT;
+ else
+ return REG_REQ_OK;
- return REG_REQ_INTERSECT;
}
/**
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 00977873300c..d0e6d351aba8 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -292,12 +292,15 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
skb_dst_force(skb);
+ dev_hold(skb->dev);
nexthdr = x->type->input(x, skb);
if (nexthdr == -EINPROGRESS)
return 0;
resume:
+ dev_put(skb->dev);
+
spin_lock(&x->lock);
if (nexthdr <= 0) {
if (nexthdr == -EBADMSG) {
diff --git a/sound/soc/codecs/audio-ext-clk.c b/sound/soc/codecs/audio-ext-clk.c
index 511bea3070e3..013021e08001 100644
--- a/sound/soc/codecs/audio-ext-clk.c
+++ b/sound/soc/codecs/audio-ext-clk.c
@@ -28,6 +28,7 @@
enum clk_mux {
AP_CLK2,
LPASS_MCLK,
+ LPASS_MCLK2,
};
struct pinctrl_info {
@@ -77,6 +78,15 @@ static const struct afe_clk_cfg lpass_default = {
0,
};
+static struct afe_clk_set lpass_default2 = {
+ Q6AFE_LPASS_CLK_CONFIG_API_VERSION,
+ Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR,
+ Q6AFE_LPASS_IBIT_CLK_12_P288_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+};
+
static inline struct audio_ext_ap_clk *to_audio_ap_clk(struct clk *clk)
{
return container_of(clk, struct audio_ext_ap_clk, c);
@@ -224,6 +234,58 @@ err:
kfree(lpass_clk);
}
+static int audio_ext_lpass_mclk2_prepare(struct clk *clk)
+{
+ struct audio_ext_lpass_mclk *audio_lpass_mclk2;
+ struct pinctrl_info *pnctrl_info;
+ int ret;
+
+ audio_lpass_mclk2 = container_of(clk, struct audio_ext_lpass_mclk, c);
+ pnctrl_info = &audio_lpass_mclk2->pnctrl_info;
+
+ if (pnctrl_info->pinctrl) {
+ ret = pinctrl_select_state(pnctrl_info->pinctrl,
+ pnctrl_info->active);
+ if (ret) {
+ pr_err("%s: active state select failed with %d\n",
+ __func__, ret);
+ return -EIO;
+ }
+ }
+
+ lpass_default2.enable = 1;
+ ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &lpass_default2);
+ if (ret < 0) {
+ pr_err("%s: failed to set clock, ret = %d\n", __func__, ret);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void audio_ext_lpass_mclk2_unprepare(struct clk *clk)
+{
+ struct audio_ext_lpass_mclk *audio_lpass_mclk2;
+ struct pinctrl_info *pnctrl_info;
+ int ret;
+
+ audio_lpass_mclk2 = container_of(clk, struct audio_ext_lpass_mclk, c);
+ pnctrl_info = &audio_lpass_mclk2->pnctrl_info;
+
+ if (pnctrl_info->pinctrl) {
+ ret = pinctrl_select_state(pnctrl_info->pinctrl,
+ pnctrl_info->sleep);
+ if (ret)
+ pr_err("%s: sleep state select failed with %d\n",
+ __func__, ret);
+ }
+
+ lpass_default2.enable = 0;
+ ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &lpass_default2);
+ if (ret < 0)
+ pr_err("%s: failed to reset clock, ret = %d\n", __func__, ret);
+}
+
static struct clk_ops audio_ext_ap_clk_ops = {
.prepare = audio_ext_clk_prepare,
.unprepare = audio_ext_clk_unprepare,
@@ -239,6 +301,11 @@ static struct clk_ops audio_ext_lpass_mclk_ops = {
.unprepare = audio_ext_lpass_mclk_unprepare,
};
+static struct clk_ops audio_ext_lpass_mclk2_ops = {
+ .prepare = audio_ext_lpass_mclk2_prepare,
+ .unprepare = audio_ext_lpass_mclk2_unprepare,
+};
+
static struct audio_ext_pmi_clk audio_pmi_clk = {
.gpio = -EINVAL,
.c = {
@@ -273,11 +340,20 @@ static struct audio_ext_lpass_mclk audio_lpass_mclk = {
},
};
+static struct audio_ext_lpass_mclk audio_lpass_mclk2 = {
+ .c = {
+ .dbg_name = "audio_ext_lpass_mclk2",
+ .ops = &audio_ext_lpass_mclk2_ops,
+ CLK_INIT(audio_lpass_mclk2.c),
+ },
+};
+
static struct clk_lookup audio_ref_clock[] = {
CLK_LIST(audio_ap_clk),
CLK_LIST(audio_pmi_clk),
CLK_LIST(audio_ap_clk2),
CLK_LIST(audio_lpass_mclk),
+ CLK_LIST(audio_lpass_mclk2),
};
static int audio_get_pinctrl(struct platform_device *pdev, enum clk_mux mux)
@@ -293,6 +369,9 @@ static int audio_get_pinctrl(struct platform_device *pdev, enum clk_mux mux)
case LPASS_MCLK:
pnctrl_info = &audio_lpass_mclk.pnctrl_info;
break;
+ case LPASS_MCLK2:
+ pnctrl_info = &audio_lpass_mclk2.pnctrl_info;
+ break;
default:
dev_err(&pdev->dev, "%s Not a valid MUX ID: %d\n",
__func__, mux);
@@ -368,6 +447,11 @@ static int audio_ref_clk_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "%s: Parsing pinctrl %s failed\n",
__func__, "LPASS_MCLK");
+ ret = audio_get_pinctrl(pdev, LPASS_MCLK2);
+ if (ret)
+ dev_dbg(&pdev->dev, "%s: Parsing pinctrl %s failed\n",
+ __func__, "LPASS_MCLK2");
+
ret = of_msm_clock_register(pdev->dev.of_node, audio_ref_clock,
ARRAY_SIZE(audio_ref_clock));
if (ret)
@@ -458,6 +542,12 @@ static int audio_ref_clk_remove(struct platform_device *pdev)
pnctrl_info->pinctrl = NULL;
}
+ pnctrl_info = &audio_lpass_mclk2.pnctrl_info;
+ if (pnctrl_info->pinctrl) {
+ devm_pinctrl_put(pnctrl_info->pinctrl);
+ pnctrl_info->pinctrl = NULL;
+ }
+
return 0;
}
diff --git a/sound/soc/codecs/msm8x16-wcd.c b/sound/soc/codecs/msm8x16-wcd.c
index 4fa9be38d2d3..8d7970b01d7a 100644
--- a/sound/soc/codecs/msm8x16-wcd.c
+++ b/sound/soc/codecs/msm8x16-wcd.c
@@ -2183,6 +2183,51 @@ static int msm8x16_wcd_boost_option_set(struct snd_kcontrol *kcontrol,
return 0;
}
+static int msm8x16_wcd_spk_boost_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
+
+ if (msm8x16_wcd->spk_boost_set == false) {
+ ucontrol->value.integer.value[0] = 0;
+ } else if (msm8x16_wcd->spk_boost_set == true) {
+ ucontrol->value.integer.value[0] = 1;
+ } else {
+ dev_err(codec->dev, "%s: ERROR: Unsupported Speaker Boost = %d\n",
+ __func__, msm8x16_wcd->spk_boost_set);
+ return -EINVAL;
+ }
+
+ dev_dbg(codec->dev, "%s: msm8x16_wcd->spk_boost_set = %d\n", __func__,
+ msm8x16_wcd->spk_boost_set);
+ return 0;
+}
+
+static int msm8x16_wcd_spk_boost_set(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ msm8x16_wcd->spk_boost_set = false;
+ break;
+ case 1:
+ msm8x16_wcd->spk_boost_set = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+ dev_dbg(codec->dev, "%s: msm8x16_wcd->spk_boost_set = %d\n",
+ __func__, msm8x16_wcd->spk_boost_set);
+ return 0;
+}
+
static int msm8x16_wcd_ext_spk_boost_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -2546,6 +2591,9 @@ static const struct snd_kcontrol_new msm8x16_wcd_snd_controls[] = {
SOC_ENUM_EXT("EAR PA Gain", msm8x16_wcd_ear_pa_gain_enum[0],
msm8x16_wcd_pa_gain_get, msm8x16_wcd_pa_gain_put),
+ SOC_ENUM_EXT("Speaker Boost", msm8x16_wcd_spk_boost_ctl_enum[0],
+ msm8x16_wcd_spk_boost_get, msm8x16_wcd_spk_boost_set),
+
SOC_ENUM_EXT("Ext Spk Boost", msm8x16_wcd_ext_spk_boost_ctl_enum[0],
msm8x16_wcd_ext_spk_boost_get, msm8x16_wcd_ext_spk_boost_set),
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index 08a067de9e91..b0ee24d4089d 100644
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -357,6 +357,12 @@ enum {
HPH_PA_DELAY,
SB_CLK_GEAR,
CLASSH_CONFIG,
+ ANC_MIC_AMIC1,
+ ANC_MIC_AMIC2,
+ ANC_MIC_AMIC3,
+ ANC_MIC_AMIC4,
+ ANC_MIC_AMIC5,
+ ANC_MIC_AMIC6,
};
enum {
@@ -552,6 +558,7 @@ static struct snd_soc_dai_driver tasha_dai[];
static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv);
static int tasha_config_compander(struct snd_soc_codec *, int, int);
+static void tasha_codec_set_tx_hold(struct snd_soc_codec *, u16, bool);
/* Hold instance to soundwire platform device */
struct tasha_swr_ctrl_data {
@@ -3593,7 +3600,7 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w,
WCD9335_CDC_ANC0_IIR_COEFF_2_CTL);
anc_writes_size = anc_cal_size / 2;
snd_soc_update_bits(codec,
- WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x38);
+ WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39);
} else if (!strcmp(w->name, "RX INT2 DAC") ||
!strcmp(w->name, "RX INT4 DAC")) {
tasha_realign_anc_coeff(codec,
@@ -3601,7 +3608,7 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w,
WCD9335_CDC_ANC1_IIR_COEFF_2_CTL);
i = anc_cal_size / 2;
snd_soc_update_bits(codec,
- WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x38);
+ WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39);
}
for (; i < anc_writes_size; i++) {
@@ -3611,16 +3618,23 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w,
if (!strcmp(w->name, "RX INT1 DAC") ||
!strcmp(w->name, "RX INT3 DAC")) {
snd_soc_update_bits(codec,
- WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x00);
+ WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08);
} else if (!strcmp(w->name, "RX INT2 DAC") ||
!strcmp(w->name, "RX INT4 DAC")) {
snd_soc_update_bits(codec,
- WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x00);
+ WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08);
}
if (!hwdep_cal)
release_firmware(fw);
break;
+ case SND_SOC_DAPM_POST_PMU:
+ /* Remove ANC Rx from reset */
+ snd_soc_update_bits(codec, WCD9335_CDC_ANC0_CLK_RESET_CTL,
+ 0x08, 0x00);
+ snd_soc_update_bits(codec, WCD9335_CDC_ANC1_CLK_RESET_CTL,
+ 0x08, 0x00);
+ break;
case SND_SOC_DAPM_POST_PMD:
if (!strcmp(w->name, "ANC HPHL PA") ||
!strcmp(w->name, "ANC EAR PA") ||
@@ -3660,6 +3674,22 @@ err:
return ret;
}
+static void tasha_codec_clear_anc_tx_hold(struct tasha_priv *tasha)
+{
+ if (test_and_clear_bit(ANC_MIC_AMIC1, &tasha->status_mask))
+ tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC1, false);
+ if (test_and_clear_bit(ANC_MIC_AMIC2, &tasha->status_mask))
+ tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC2, false);
+ if (test_and_clear_bit(ANC_MIC_AMIC3, &tasha->status_mask))
+ tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC3, false);
+ if (test_and_clear_bit(ANC_MIC_AMIC4, &tasha->status_mask))
+ tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC4, false);
+ if (test_and_clear_bit(ANC_MIC_AMIC5, &tasha->status_mask))
+ tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC5, false);
+ if (test_and_clear_bit(ANC_MIC_AMIC6, &tasha->status_mask))
+ tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC6, false);
+}
+
static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha,
int mode, int event)
{
@@ -3678,6 +3708,13 @@ static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha,
scale_val = 0x1;
break;
}
+ if (tasha->anc_func) {
+ /* Clear Tx FE HOLD if both PAs are enabled */
+ if ((snd_soc_read(tasha->codec, WCD9335_ANA_HPH) &
+ 0xC0) == 0xC0) {
+ tasha_codec_clear_anc_tx_hold(tasha);
+ }
+ }
break;
case SND_SOC_DAPM_PRE_PMD:
scale_val = 0x6;
@@ -3744,9 +3781,19 @@ static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ if ((!(strcmp(w->name, "ANC HPHR PA"))) &&
+ (test_bit(HPH_PA_DELAY, &tasha->status_mask))) {
+ snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0);
+ }
set_bit(HPH_PA_DELAY, &tasha->status_mask);
break;
case SND_SOC_DAPM_POST_PMU:
+ if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) != 0xC0)
+ /* If PA_EN is not set (potentially in ANC case) then
+ * do nothing for POST_PMU and let left channel handle
+ * everything.
+ */
+ break;
/*
* 7ms sleep is required after PA is enabled as per
* HW requirement
@@ -3764,13 +3811,31 @@ static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
snd_soc_update_bits(codec,
WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
0x10, 0x00);
+
+ if (!(strcmp(w->name, "ANC HPHR PA"))) {
+ /* Do everything needed for left channel */
+ snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL,
+ 0x10, 0x00);
+ /* Remove mix path mute if it is enabled */
+ if ((snd_soc_read(codec,
+ WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) &
+ 0x10)
+ snd_soc_update_bits(codec,
+ WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
+ 0x10, 0x00);
+ /* Remove ANC Rx from reset */
+ ret = tasha_codec_enable_anc(w, kcontrol, event);
+ }
tasha_codec_override(codec, hph_mode, event);
break;
+
case SND_SOC_DAPM_PRE_PMD:
blocking_notifier_call_chain(&tasha->notifier,
WCD_EVENT_PRE_HPHR_PA_OFF,
&tasha->mbhc);
tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
+ if (!(strcmp(w->name, "ANC HPHR PA")))
+ snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x40, 0x00);
break;
case SND_SOC_DAPM_POST_PMD:
/* 5ms sleep is required after PA is disabled as per
@@ -3806,9 +3871,19 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ if ((!(strcmp(w->name, "ANC HPHL PA"))) &&
+ (test_bit(HPH_PA_DELAY, &tasha->status_mask))) {
+ snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0);
+ }
set_bit(HPH_PA_DELAY, &tasha->status_mask);
break;
case SND_SOC_DAPM_POST_PMU:
+ if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) != 0xC0)
+ /* If PA_EN is not set (potentially in ANC case) then
+ * do nothing for POST_PMU and let right channel handle
+ * everything.
+ */
+ break;
/*
* 7ms sleep is required after PA is enabled as per
* HW requirement
@@ -3827,6 +3902,22 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
snd_soc_update_bits(codec,
WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
0x10, 0x00);
+
+ if (!(strcmp(w->name, "ANC HPHL PA"))) {
+ /* Do everything needed for right channel */
+ snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL,
+ 0x10, 0x00);
+ /* Remove mix path mute if it is enabled */
+ if ((snd_soc_read(codec,
+ WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) &
+ 0x10)
+ snd_soc_update_bits(codec,
+ WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
+ 0x10, 0x00);
+
+ /* Remove ANC Rx from reset */
+ ret = tasha_codec_enable_anc(w, kcontrol, event);
+ }
tasha_codec_override(codec, hph_mode, event);
break;
case SND_SOC_DAPM_PRE_PMD:
@@ -3834,6 +3925,8 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
WCD_EVENT_PRE_HPHL_PA_OFF,
&tasha->mbhc);
tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
+ if (!(strcmp(w->name, "ANC HPHL PA")))
+ snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x80, 0x00);
break;
case SND_SOC_DAPM_POST_PMD:
/* 5ms sleep is required after PA is disabled as per
@@ -3901,6 +3994,9 @@ static int tasha_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
snd_soc_update_bits(codec,
lineout_mix_vol_reg,
0x10, 0x00);
+ if (!(strcmp(w->name, "ANC LINEOUT1 PA")) ||
+ !(strcmp(w->name, "ANC LINEOUT2 PA")))
+ ret = tasha_codec_enable_anc(w, kcontrol, event);
tasha_codec_override(codec, CLS_AB, event);
break;
case SND_SOC_DAPM_POST_PMD:
@@ -5233,8 +5329,8 @@ static int tasha_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w,
{
int adc_mux_n = w->shift;
struct snd_soc_codec *codec = w->codec;
+ struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
int amic_n;
- u16 amic_reg;
dev_dbg(codec->dev, "%s: event: %d\n", __func__, event);
@@ -5242,8 +5338,13 @@ static int tasha_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMU:
amic_n = tasha_codec_find_amic_input(codec, adc_mux_n);
if (amic_n) {
- amic_reg = WCD9335_ANA_AMIC1 + amic_n - 1;
- tasha_codec_set_tx_hold(codec, amic_reg, false);
+ /*
+ * Prevent ANC Rx pop by leaving Tx FE in HOLD
+ * state until PA is up. Track AMIC being used
+ * so we can release the HOLD later.
+ */
+ set_bit(ANC_MIC_AMIC1 + amic_n - 1,
+ &tasha->status_mask);
}
break;
default:
@@ -10357,11 +10458,11 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
tasha_codec_enable_ear_pa,
SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA_E("ANC HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0,
+ SND_SOC_DAPM_PGA_E("ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0,
tasha_codec_enable_hphl_pa,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA_E("ANC HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0,
+ SND_SOC_DAPM_PGA_E("ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
tasha_codec_enable_hphr_pa,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
diff --git a/sound/soc/codecs/wsa881x-analog.c b/sound/soc/codecs/wsa881x-analog.c
index 04bccb4a8ad2..2bb6cf805926 100644
--- a/sound/soc/codecs/wsa881x-analog.c
+++ b/sound/soc/codecs/wsa881x-analog.c
@@ -903,7 +903,8 @@ static int wsa881x_startup(struct wsa881x_pdata *pdata)
if (pdata->enable_mclk) {
ret = pdata->enable_mclk(card, true);
if (ret < 0) {
- pr_err("%s: mclk enable failed %d\n",
+ dev_err_ratelimited(codec->dev,
+ "%s: mclk enable failed %d\n",
__func__, ret);
return ret;
}
@@ -966,7 +967,8 @@ static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec,
if (enable) {
ret = wsa881x_startup(wsa881x);
if (ret < 0) {
- pr_err("%s: failed to startup\n", __func__);
+ dev_err_ratelimited(codec->dev,
+ "%s: failed to startup\n", __func__);
return ret;
}
}
@@ -975,7 +977,8 @@ static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec,
if (!enable) {
ret = wsa881x_shutdown(wsa881x);
if (ret < 0)
- pr_err("%s: failed to shutdown\n", __func__);
+ dev_err_ratelimited(codec->dev,
+ "%s: failed to shutdown\n", __func__);
}
return ret;
}
@@ -984,12 +987,18 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec,
struct wsa_temp_register *wsa_temp_reg)
{
struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
if (!wsa881x) {
dev_err(codec->dev, "%s: wsa881x is NULL\n", __func__);
return -EINVAL;
}
- wsa881x_resource_acquire(codec, true);
+ ret = wsa881x_resource_acquire(codec, true);
+ if (ret) {
+ dev_err_ratelimited(codec->dev,
+ "%s: resource acquire fail\n", __func__);
+ return ret;
+ }
if (WSA881X_IS_2_0(wsa881x->version)) {
snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00);
@@ -1007,9 +1016,12 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec,
wsa_temp_reg->d2_msb = snd_soc_read(codec, WSA881X_OTP_REG_3);
wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4);
- wsa881x_resource_acquire(codec, false);
+ ret = wsa881x_resource_acquire(codec, false);
+ if (ret)
+ dev_err_ratelimited(codec->dev,
+ "%s: resource release fail\n", __func__);
- return 0;
+ return ret;
}
static int wsa881x_probe(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c
index 4322711376a6..c54957e88b04 100644
--- a/sound/soc/codecs/wsa881x.c
+++ b/sound/soc/codecs/wsa881x.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016, 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
@@ -740,6 +740,9 @@ static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w,
wsa881x_boost_ctrl(codec, ENABLE);
break;
case SND_SOC_DAPM_POST_PMD:
+ swr_slvdev_datapath_control(wsa881x->swr_slave,
+ wsa881x->swr_slave->dev_num,
+ false);
if (wsa881x->boost_enable)
wsa881x_boost_ctrl(codec, DISABLE);
wsa881x_resource_acquire(codec, DISABLE);
@@ -805,6 +808,9 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w,
regmap_multi_reg_write(wsa881x->regmap,
wsa881x_pre_pmu_pa,
ARRAY_SIZE(wsa881x_pre_pmu_pa));
+ swr_slvdev_datapath_control(wsa881x->swr_slave,
+ wsa881x->swr_slave->dev_num,
+ true);
break;
case SND_SOC_DAPM_POST_PMU:
if (WSA881X_IS_2_0(wsa881x->version)) {
diff --git a/sound/soc/msm/msm8952-dai-links.c b/sound/soc/msm/msm8952-dai-links.c
index 2b341beadd06..25ad870ad1ef 100644
--- a/sound/soc/msm/msm8952-dai-links.c
+++ b/sound/soc/msm/msm8952-dai-links.c
@@ -1512,7 +1512,7 @@ struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
{
struct snd_soc_card *card = &snd_soc_card_msm_card;
struct snd_soc_dai_link *msm8952_dai_links = NULL;
- int num_links, ret, len1, len2, len3, len4;
+ int num_links, ret, len1, len2, len3, len4 = 0;
enum codec_variant codec_ver = 0;
const char *tasha_lite[NUM_OF_TASHA_LITE_DEVICE] = {
"msm8952-tashalite-snd-card",
diff --git a/sound/soc/msm/msm8996.c b/sound/soc/msm/msm8996.c
index f06d5d365283..13cfd93bbbef 100644
--- a/sound/soc/msm/msm8996.c
+++ b/sound/soc/msm/msm8996.c
@@ -2897,7 +2897,14 @@ static int msm8996_wcd93xx_codec_up(struct snd_soc_codec *codec)
do {
if (!q6core_is_adsp_ready()) {
- pr_err("%s: ADSP Audio isn't ready\n", __func__);
+ pr_err_ratelimited("%s: ADSP Audio isn't ready\n",
+ __func__);
+ /*
+ * ADSP will be coming up after subsystem restart and
+ * it might not be fully up when the control reaches
+ * here. So, wait for 50msec before checking ADSP state
+ */
+ msleep(50);
} else {
pr_debug("%s: ADSP Audio is ready\n", __func__);
adsp_ready = 1;
diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c
index e6667cc12439..be30f8f172d6 100644
--- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c
+++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, 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.
@@ -1370,7 +1370,11 @@ static int msm_ds2_dap_handle_commands(u32 cmd, void *arg)
int ret = 0, port_id = 0;
int32_t data;
struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg;
- get_user(data, &dolby_data->data[0]);
+ if (get_user(data, &dolby_data->data[0])) {
+ pr_debug("%s error getting data\n", __func__);
+ ret = -EFAULT;
+ goto end;
+ }
pr_debug("%s: param_id %d,be_id %d,device_id 0x%x,length %d,data %d\n",
__func__, dolby_data->param_id, dolby_data->be_id,
@@ -1489,11 +1493,23 @@ static int msm_ds2_dap_set_param(u32 cmd, void *arg)
goto end;
}
+ off = ds2_dap_params_offset[idx];
+ if ((dolby_data->length <= 0) ||
+ (dolby_data->length > TOTAL_LENGTH_DS2_PARAM - off)) {
+ pr_err("%s: invalid length %d at idx %d\n",
+ __func__, dolby_data->length, idx);
+ rc = -EINVAL;
+ goto end;
+ }
+
/* cache the parameters */
ds2_dap_params[cdev].dap_params_modified[idx] += 1;
for (j = 0; j < dolby_data->length; j++) {
- off = ds2_dap_params_offset[idx];
- get_user(data, &dolby_data->data[j]);
+ if (get_user(data, &dolby_data->data[j])) {
+ pr_debug("%s:error getting data\n", __func__);
+ rc = -EFAULT;
+ goto end;
+ }
ds2_dap_params[cdev].params_val[off + j] = data;
pr_debug("%s:off %d,val[i/p:o/p]-[%d / %d]\n",
__func__, off, data,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 62a315f50a7b..1425e6633ed4 100755
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -86,9 +86,9 @@ static int quat_mi2s_switch_enable;
static int fm_pcmrx_switch_enable;
static int lsm_mux_slim_port;
static int slim0_rx_aanc_fb_port;
-static int msm_route_ec_ref_rx = 9; /* NONE */
+static int msm_route_ec_ref_rx;
static uint32_t voc_session_id = ALL_SESSION_VSID;
-static int msm_route_ext_ec_ref = AFE_PORT_INVALID;
+static int msm_route_ext_ec_ref;
static bool is_custom_stereo_on;
static bool is_ds2_on;
@@ -2338,41 +2338,44 @@ static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_widget *widget = wlist->widgets[0];
int mux = ucontrol->value.enumerated.item[0];
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- int ret = 0;
- bool state = false;
+ int ret = 1;
+ bool state = true;
+ uint16_t ext_ec_ref_port_id;
struct snd_soc_dapm_update *update = NULL;
- pr_debug("%s: msm_route_ec_ref_rx = %d value = %ld\n",
- __func__, msm_route_ext_ec_ref,
- ucontrol->value.integer.value[0]);
-
mutex_lock(&routing_lock);
- switch (ucontrol->value.integer.value[0]) {
- case EC_PORT_ID_PRIMARY_MI2S_TX:
- msm_route_ext_ec_ref = AFE_PORT_ID_PRIMARY_MI2S_TX;
- state = true;
+ msm_route_ext_ec_ref = ucontrol->value.integer.value[0];
+
+ switch (msm_route_ext_ec_ref) {
+ case EXT_EC_REF_PRI_MI2S_TX:
+ ext_ec_ref_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX;
break;
- case EC_PORT_ID_SECONDARY_MI2S_TX:
- msm_route_ext_ec_ref = AFE_PORT_ID_SECONDARY_MI2S_TX;
- state = true;
+ case EXT_EC_REF_SEC_MI2S_TX:
+ ext_ec_ref_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX;
break;
- case EC_PORT_ID_TERTIARY_MI2S_TX:
- msm_route_ext_ec_ref = AFE_PORT_ID_TERTIARY_MI2S_TX;
- state = true;
+ case EXT_EC_REF_TERT_MI2S_TX:
+ ext_ec_ref_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX;
break;
- case EC_PORT_ID_QUATERNARY_MI2S_TX:
- msm_route_ext_ec_ref = AFE_PORT_ID_QUATERNARY_MI2S_TX;
- state = true;
+ case EXT_EC_REF_QUAT_MI2S_TX:
+ ext_ec_ref_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
break;
- case EC_PORT_ID_SLIMBUS_1_TX:
- msm_route_ext_ec_ref = SLIMBUS_1_TX;
- state = true;
+ case EXT_EC_REF_QUIN_MI2S_TX:
+ ext_ec_ref_port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
break;
+ case EXT_EC_REF_SLIM_1_TX:
+ ext_ec_ref_port_id = SLIMBUS_1_TX;
+ break;
+ case EXT_EC_REF_NONE:
default:
- msm_route_ext_ec_ref = AFE_PORT_INVALID;
+ ext_ec_ref_port_id = AFE_PORT_INVALID;
+ state = false;
break;
}
- if (!voc_set_ext_ec_ref(msm_route_ext_ec_ref, state)) {
+
+ pr_debug("%s: val = %d ext_ec_ref_port_id = 0x%0x state = %d\n",
+ __func__, msm_route_ext_ec_ref, ext_ec_ref_port_id, state);
+
+ if (!voc_set_ext_ec_ref(ext_ec_ref_port_id, state)) {
mutex_unlock(&routing_lock);
snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e, update);
} else {
@@ -2383,11 +2386,12 @@ static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol,
}
static const char * const ext_ec_ref_rx[] = {"NONE", "PRI_MI2S_TX",
- "SEC_MI2S_TX", "TERT_MI2S_TX",
- "QUAT_MI2S_TX", "SLIM_1_TX"};
+ "SEC_MI2S_TX", "TERT_MI2S_TX",
+ "QUAT_MI2S_TX", "QUIN_MI2S_TX",
+ "SLIM_1_TX"};
static const struct soc_enum msm_route_ext_ec_ref_rx_enum[] = {
- SOC_ENUM_SINGLE_EXT(6, ext_ec_ref_rx),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ext_ec_ref_rx), ext_ec_ref_rx),
};
static const struct snd_kcontrol_new voc_ext_ec_mux =
@@ -8665,7 +8669,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SLIMBUS_3_RX", NULL, "SLIMBUS3_DL_HL"},
{"SLIMBUS4_DL_HL", "Switch", "SLIM4_DL_HL"},
{"SLIMBUS_4_RX", NULL, "SLIMBUS4_DL_HL"},
- {"SLIMBUS6_DL_HL", "Switch", "SLIM6_DL_HL"},
+ {"SLIMBUS6_DL_HL", "Switch", "SLIM0_DL_HL"},
{"SLIMBUS_6_RX", NULL, "SLIMBUS6_DL_HL"},
{"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"},
{"SLIM1_UL_HL", NULL, "SLIMBUS_1_TX"},
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index e191aba79138..f1ec04dafeb5 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -306,6 +306,16 @@ enum msm_pcm_routing_event {
MSM_PCM_RT_EVT_MAX,
};
+enum {
+ EXT_EC_REF_NONE = 0,
+ EXT_EC_REF_PRI_MI2S_TX,
+ EXT_EC_REF_SEC_MI2S_TX,
+ EXT_EC_REF_TERT_MI2S_TX,
+ EXT_EC_REF_QUAT_MI2S_TX,
+ EXT_EC_REF_QUIN_MI2S_TX,
+ EXT_EC_REF_SLIM_1_TX,
+};
+
#define INVALID_SESSION -1
#define SESSION_TYPE_RX 0
#define SESSION_TYPE_TX 1
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 9ca09d2b6c71..339ce6bc8e75 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -675,7 +675,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
int err = -ENODEV;
down_read(&chip->shutdown_rwsem);
- if (chip->probing && chip->in_pm)
+ if (chip->probing || chip->in_pm)
err = 0;
else if (!chip->shutdown)
err = usb_autopm_get_interface(chip->pm_intf);