diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2018-09-22 21:48:38 -0700 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2018-09-22 21:48:38 -0700 |
commit | 0902c454f8e67dec5c0bcc20e7a425ce574edfca (patch) | |
tree | db3da1660306090ca7ac82e54e864f77b98ec628 | |
parent | ebaed828f970437ebbb9484c6ebeaf09e3e28e58 (diff) | |
parent | bd0761b7eb7ca25a71029396c98ac64e39a78378 (diff) |
Merge bd0761b7eb7ca25a71029396c98ac64e39a78378 on remote branchLA.UM.7.6.2.r1-03400-89xx.0
Change-Id: I52c789e44a35291d40b7fe6052c496bcaaabb2f4
93 files changed, 1831 insertions, 717 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index 74e90e64ee9d..f7df78dc7cde 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -104,6 +104,9 @@ SoCs: - SXR1130 compatible = "qcom,sxr1130" +- QRD1130 + compatible = "qcom,sxr1130-qrd" + - MSM8952 compatible = "qcom,msm8952" diff --git a/Documentation/devicetree/bindings/input/qti-haptics.txt b/Documentation/devicetree/bindings/input/qti-haptics.txt index 2c4f4f02ae34..b3daa49fe443 100644 --- a/Documentation/devicetree/bindings/input/qti-haptics.txt +++ b/Documentation/devicetree/bindings/input/qti-haptics.txt @@ -130,6 +130,15 @@ waveforms/effects: [5:1]: waveform amplitude [0]: reserved. +- qcom,wf-vmax-mv + Usage: optional + Value type: <u32> + Definition: Specifies the maximum allowed output voltage in millivolts + for this effect. Value specified here will be rounded + off to the closest multiple of 116 mV. Allowed values: + 0 to 3596. If this is not specified, the value defined in + "qcom,vmax-mv" will be applied. + - qcom,wf-play-rate-us Usage: optional Value type: <u32> diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 167070895498..ddcb90cee84f 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -306,6 +306,7 @@ IRQ devm_request_any_context_irq() devm_request_irq() devm_request_threaded_irq() + devm_irq_sim_init() LED devm_led_classdev_register() diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig index 442bc064ed50..4ee1f0ba991b 100644 --- a/arch/arm/configs/msm8909-perf_defconfig +++ b/arch/arm/configs/msm8909-perf_defconfig @@ -33,6 +33,7 @@ CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y # CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y +# CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_OPROFILE=m @@ -150,8 +151,6 @@ CONFIG_NETFILTER_XT_MATCH_STRING=y CONFIG_NETFILTER_XT_MATCH_TIME=y CONFIG_NETFILTER_XT_MATCH_U32=y CONFIG_NF_CONNTRACK_IPV4=y -CONFIG_NF_DUP_IPV4=y -CONFIG_NF_LOG_IPV4=y CONFIG_IP_NF_IPTABLES=y CONFIG_IP_NF_MATCH_AH=y CONFIG_IP_NF_MATCH_ECN=y @@ -170,8 +169,6 @@ CONFIG_IP_NF_ARPTABLES=y CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y -CONFIG_NF_DUP_IPV6=y -CONFIG_NF_LOG_IPV6=y CONFIG_IP6_NF_IPTABLES=y CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y @@ -252,7 +249,6 @@ CONFIG_CNSS=y CONFIG_CNSS_SDIO=y CONFIG_CLD_HL_SDIO_CORE=y CONFIG_INPUT_EVDEV=y -CONFIG_INPUT_EVBUG=m CONFIG_KEYBOARD_GPIO=y CONFIG_INPUT_JOYSTICK=y CONFIG_INPUT_TOUCHSCREEN=y diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig index 787b38e0c357..428cd92dba78 100644 --- a/arch/arm/configs/msm8909_defconfig +++ b/arch/arm/configs/msm8909_defconfig @@ -36,6 +36,7 @@ CONFIG_PROFILING=y CONFIG_OPROFILE=m CONFIG_KPROBES=y CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_ARCH_MMAP_RND_BITS=16 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y @@ -56,6 +57,7 @@ CONFIG_CMA=y CONFIG_CMA_DEBUGFS=y CONFIG_ZSMALLOC=y CONFIG_BALANCE_ANON_FILE_RECLAIM=y +CONFIG_PROCESS_RECLAIM=y CONFIG_SECCOMP=y CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y @@ -573,13 +575,12 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SMACK=y CONFIG_SECURITY_APPARMOR=y CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_CRYPTO_CTR=y -CONFIG_CRYPTO_XTS=y CONFIG_CRYPTO_XCBC=y CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_DEV_QCE=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y CONFIG_CRYPTO_DEV_QCRYPTO=y CONFIG_CRYPTO_DEV_QCEDEV=y diff --git a/arch/arm/configs/msm8909w-perf_defconfig b/arch/arm/configs/msm8909w-perf_defconfig index cb12130fd2a2..60efbebc52aa 100644 --- a/arch/arm/configs/msm8909w-perf_defconfig +++ b/arch/arm/configs/msm8909w-perf_defconfig @@ -80,6 +80,7 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y @@ -91,6 +92,7 @@ CONFIG_INET6_AH=y CONFIG_INET6_ESP=y CONFIG_INET6_IPCOMP=y CONFIG_IPV6_MIP6=y +CONFIG_IPV6_VTI=y CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_NETFILTER=y @@ -262,6 +264,7 @@ CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y CONFIG_TOUCHSCREEN_FTS=y CONFIG_INPUT_MISC=y CONFIG_INPUT_QPNP_POWER_ON=y +CONFIG_INPUT_QTI_HAPTICS=y CONFIG_INPUT_UINPUT=y # CONFIG_DEVMEM is not set # CONFIG_DEVKMEM is not set @@ -372,7 +375,6 @@ CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_MSM=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y -CONFIG_LEDS_QPNP_HAPTICS=y CONFIG_LEDS_TRIGGERS=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_QPNP=y @@ -469,6 +471,7 @@ CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_FRAME_WARN=2048 +CONFIG_MAGIC_SYSRQ=y CONFIG_PAGE_EXTENSION=y CONFIG_PANIC_ON_RECURSIVE_FAULT=y CONFIG_WQ_WATCHDOG=y @@ -487,6 +490,7 @@ CONFIG_LSM_MMAP_MIN_ADDR=4096 CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SMACK=y +CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_XCBC=y CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_TWOFISH=y diff --git a/arch/arm/configs/msm8909w_defconfig b/arch/arm/configs/msm8909w_defconfig index a15ab9c708bb..225e18e31172 100644 --- a/arch/arm/configs/msm8909w_defconfig +++ b/arch/arm/configs/msm8909w_defconfig @@ -81,6 +81,7 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y @@ -92,6 +93,7 @@ CONFIG_INET6_AH=y CONFIG_INET6_ESP=y CONFIG_INET6_IPCOMP=y CONFIG_IPV6_MIP6=y +CONFIG_IPV6_VTI=y CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_NETFILTER=y @@ -251,6 +253,7 @@ CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y CONFIG_TOUCHSCREEN_FTS=y CONFIG_INPUT_MISC=y CONFIG_INPUT_QPNP_POWER_ON=y +CONFIG_INPUT_QTI_HAPTICS=y CONFIG_INPUT_UINPUT=y # CONFIG_DEVMEM is not set # CONFIG_DEVKMEM is not set @@ -344,6 +347,8 @@ CONFIG_USB_CONFIGFS_NCM=y CONFIG_USB_CONFIGFS_RMNET_BAM=y CONFIG_USB_CONFIGFS_MASS_STORAGE=y CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_MTP=y +CONFIG_USB_CONFIGFS_F_PTP=y CONFIG_USB_CONFIGFS_F_ACC=y CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y CONFIG_USB_CONFIGFS_UEVENT=y @@ -364,7 +369,6 @@ CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_MSM=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y -CONFIG_LEDS_QPNP_HAPTICS=y CONFIG_LEDS_TRIGGERS=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_QPNP=y @@ -464,6 +468,7 @@ CONFIG_DEBUG_INFO=y CONFIG_FRAME_WARN=2048 CONFIG_PAGE_OWNER=y CONFIG_PAGE_OWNER_ENABLE_DEFAULT=y +CONFIG_MAGIC_SYSRQ=y CONFIG_SLUB_DEBUG_PANIC_ON=y CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_MEMORY_INIT=y @@ -514,7 +519,7 @@ CONFIG_LSM_MMAP_MIN_ADDR=4096 CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SMACK=y -CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_XTS=y CONFIG_CRYPTO_XCBC=y CONFIG_CRYPTO_MD4=y diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig index 21cbde57a04a..528cb27539b5 100644 --- a/arch/arm/configs/msm8953_defconfig +++ b/arch/arm/configs/msm8953_defconfig @@ -616,6 +616,7 @@ CONFIG_DEVFREQ_SIMPLE_DEV=y CONFIG_QCOM_DEVFREQ_DEVBW=y CONFIG_SPDM_SCM=y CONFIG_DEVFREQ_SPDM=y +CONFIG_EXTCON_USB_GPIO=y CONFIG_IIO=y CONFIG_PWM=y CONFIG_PWM_QPNP=y diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig index 7ca91802b274..6b4373368b62 100644 --- a/arch/arm/mach-qcom/Kconfig +++ b/arch/arm/mach-qcom/Kconfig @@ -107,8 +107,8 @@ config ARCH_MSM8909 select PM_OPP select MSM_DEVFREQ_DEVBW select DEVFREQ_SIMPLE_DEV - select DEVFREQ_GOV_MSM_BW_HWMON - select MSM_BIMC_BWMON + select DEVFREQ_GOV_QCOM_BW_HWMON + select QCOM_BIMC_BWMON select CLKDEV_LOOKUP select HAVE_CLK select HAVE_CLK_PREPARE diff --git a/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi b/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi index c8330bd689d6..e4581c5e80d8 100644 --- a/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi @@ -437,24 +437,55 @@ &pm660_1 { pm660_haptics: qcom,haptics@c000 { - compatible = "qcom,qpnp-haptics"; + compatible = "qcom,pm660-haptics"; reg = <0xc000 0x100>; interrupts = <0x1 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>, <0x1 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hap-sc-irq", "hap-play-irq"; - qcom,pmic-revid = <&pm660_revid>; - qcom,pmic-misc = <&pm660_misc>; - qcom,misc-clk-trim-error-reg = <0xf3>; - qcom,actuator-type = <1>; - qcom,play-mode = "direct"; + qcom,actuator-type = "erm"; qcom,vmax-mv = <3200>; - qcom,ilim-ma = <800>; - qcom,sc-dbc-cycles = <8>; - qcom,wave-play-rate-us = <6667>; - qcom,en-brake; - qcom,lra-high-z = "opt0"; - qcom,lra-auto-res-mode = "qwd"; - qcom,lra-res-cal-period = <4>; + qcom,ilim-ma = <400>; + qcom,play-rate-us = <10000>; + wf_0 { + /* CLICK */ + qcom,effect-id = <0>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e 3e]; + qcom,wf-brake-pattern = [01 00 00 00]; + }; + wf_1 { + /* DOUBLE CLICK */ + qcom,effect-id = <1>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 7e 02 02 02 02 02 02]; + qcom,wf-repeat-count = <2>; + qcom,wf-s-repeat-count = <1>; + }; + wf_2 { + /* TICK */ + qcom,effect-id = <2>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 7e]; + }; + wf_3 { + /* THUD */ + qcom,effect-id = <3>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 7e 7e]; + }; + wf_4 { + /* POP */ + qcom,effect-id = <4>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 7e]; + }; + wf_5 { + /* HEAVY CLICK */ + qcom,effect-id = <5>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 7e 7e]; + qcom,wf-play-rate-us = <6667>; + }; }; }; diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index ef0ac4d43f80..8b0013f6c989 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -185,7 +185,8 @@ ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y) sxr1130-usbc-external-codec-mtp-overlay.dtbo \ sxr1130-usbc-external-codec-pm660a-mtp-overlay.dtbo \ sxr1130-usbc-mtp-overlay.dtbo \ - sxr1130-usbc-pm660a-mtp-overlay.dtbo + sxr1130-usbc-pm660a-mtp-overlay.dtbo \ + sxr1130-qrd-overlay.dtbo sdm670-cdp-overlay.dtbo-base := sdm670.dtb sdm670-mtp-overlay.dtbo-base := sdm670.dtb @@ -259,6 +260,7 @@ sxr1130-usbc-external-codec-mtp-overlay.dtbo-base := sxr1130.dtb sxr1130-usbc-external-codec-pm660a-mtp-overlay.dtbo-base := sxr1130.dtb sxr1130-usbc-mtp-overlay.dtbo-base := sxr1130.dtb sxr1130-usbc-pm660a-mtp-overlay.dtbo-base := sxr1130.dtb +sxr1130-qrd-overlay.dtbo-base := sxr1130.dtb else dtb-$(CONFIG_ARCH_SDM670) += sdm670-rumi.dtb \ @@ -328,7 +330,8 @@ dtb-$(CONFIG_ARCH_SDM670) += sdm670-rumi.dtb \ sxr1130-usbc-external-codec-mtp.dtb \ sxr1130-usbc-external-codec-pm660a-mtp.dtb \ sxr1130-usbc-mtp.dtb \ - sxr1130-usbc-pm660a-mtp.dtb + sxr1130-usbc-pm660a-mtp.dtb \ + sxr1130-qrd.dtb endif ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y) diff --git a/arch/arm64/boot/dts/qcom/apq8009-dragon.dts b/arch/arm64/boot/dts/qcom/apq8009-dragon.dts index 041563b0d08e..314af114555f 100644 --- a/arch/arm64/boot/dts/qcom/apq8009-dragon.dts +++ b/arch/arm64/boot/dts/qcom/apq8009-dragon.dts @@ -16,7 +16,6 @@ #include "msm8909-mtp.dtsi" #include "8909-pm8916.dtsi" #include "msm8909-pm8916-mtp.dtsi" -#include "apq8009-audio-external_codec.dtsi" / { model = "Qualcomm Technologies, Inc. APQ8009 Dragon Board"; @@ -26,24 +25,95 @@ }; &soc { - ext-codec { + cdc_dmic_gpios: cdc_dmic_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&cdc_dmic0_clk_act &cdc_dmic0_data_act>; + pinctrl-1 = <&cdc_dmic0_clk_sus &cdc_dmic0_data_sus>; + }; + + cdc_prim_mi2s_gpios: msm_cdc_pinctrl_pri { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&pri_mi2s_sleep &pri_mi2s_ws_sleep + &pri_mi2s_dout_sleep &pri_mi2s_din_sleep + &ext_amp_ctrl_sleep &_mute_sleep>; + pinctrl-1 = <&pri_mi2s_active &pri_mi2s_ws_active + &pri_mi2s_dout_active &pri_mi2s_din_active + &ext_amp_ctrl_active &_mute_active>; + + }; + + audio_codec_mtp: sound { + status = "ok"; + qcom,msm-hs-micbias-type = "internal"; + qcom,model = "msm8909-212-som-snd-card"; qcom,msm-mbhc-hphl-swh = <0>; + qcom,audio-routing = - "AIF4 VI", "MCLK", "RX_BIAS", "MCLK", - "MADINPUT", "MCLK", - "AMIC2", "MIC BIAS2", - "MIC BIAS2", "Headset Mic", - "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", - "SpkrLeft IN", "SPK1 OUT", - "SpkrRight IN", "SPK2 OUT"; + "SPK_RX_BIAS", "MCLK", + "INT_LDO_H", "MCLK", + "RX_I2S_CLK", "MCLK", + "TX_I2S_CLK", "MCLK", + "MIC BIAS Internal1", "Handset Mic", + "MIC BIAS Internal2", "Headset Mic", + "MIC BIAS Internal1", "Secondary Mic", + "AMIC1", "MIC BIAS Internal1", + "AMIC2", "MIC BIAS Internal2", + "AMIC3", "MIC BIAS Internal1", + "DMIC1", "DIGITAL_REGULATOR", + "DIGITAL_REGULATOR", "Digital Mic1", + "DMIC2", "DIGITAL_REGULATOR", + "DIGITAL_REGULATOR", "Digital Mic2"; + + qcom,pri-mi2s-gpios = <&cdc_prim_mi2s_gpios>; + qcom,cdc-dmic-gpios = <&cdc_dmic_gpios>; + + qcom,afe-rxtx-lb; + asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, + <&loopback>, <&compress>, <&hostless>, + <&afe>, <&lsm>, <&routing>, <&pcm_noirq>; + 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-pcm-dsp-noirq"; + asoc-cpu = <&dai_pri_auxpcm>, + <&dai_mi2s0>, <&dai_mi2s1>, + <&dai_mi2s2>, <&dai_mi2s3>, + <&dai_mi2s4>, <&dai_mi2s5>, + <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>, + <&sb_3_rx>, <&sb_3_tx>, <&sb_4_rx>, <&sb_4_tx>, + <&bt_sco_rx>, <&bt_sco_tx>, + <&int_fm_rx>, <&int_fm_tx>, + <&afe_pcm_rx>, <&afe_pcm_tx>, + <&afe_proxy_rx>, <&afe_proxy_tx>, + <&incall_record_rx>, <&incall_record_tx>, + <&incall_music_rx>, <&incall_music_2_rx>, + <&bt_a2dp_rx>, <&afe_loopback_tx>; + + asoc-cpu-names = "msm-dai-q6-auxpcm.1", + "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", + "msm-dai-q6-mi2s.4", "msm-dai-q6-mi2s.6", + "msm-dai-q6-dev.16384", "msmdai-q6-dev.16385", + "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387", + "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391", + "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393", + "msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289", + "msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293", + "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", + "msm-dai-q6-dev.12290", "msm-dai-q6-dev.24577"; + + asoc-codec = <&stub_codec>, <&msm_digital_codec>, + <&pmic_analog_codec>; + asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec", + "analog-codec"; }; sound-9335 { @@ -97,6 +167,72 @@ status = "disabled"; }; +&pm8916_1 { + pmic_analog_codec: analog-codec@f000 { + compatible = "qcom,pmic-analog-codec"; + reg = <0xf000 0x200>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-parent = <&spmi_bus>; + interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>, + <0x1 0xf0 0x1 IRQ_TYPE_NONE>, + <0x1 0xf0 0x2 IRQ_TYPE_NONE>, + <0x1 0xf0 0x3 IRQ_TYPE_NONE>, + <0x1 0xf0 0x4 IRQ_TYPE_NONE>, + <0x1 0xf0 0x5 IRQ_TYPE_NONE>, + <0x1 0xf0 0x6 IRQ_TYPE_NONE>, + <0x1 0xf0 0x7 IRQ_TYPE_NONE>, + <0x1 0xf1 0x0 IRQ_TYPE_NONE>, + <0x1 0xf1 0x1 IRQ_TYPE_NONE>, + <0x1 0xf1 0x2 IRQ_TYPE_NONE>, + <0x1 0xf1 0x3 IRQ_TYPE_NONE>, + <0x1 0xf1 0x4 IRQ_TYPE_NONE>, + <0x1 0xf1 0x5 IRQ_TYPE_NONE>; + interrupt-names = "spk_cnp_int", + "spk_clip_int", + "spk_ocp_int", + "ins_rem_det1", + "but_rel_det", + "but_press_det", + "ins_rem_det", + "mbhc_int", + "ear_ocp_int", + "hphr_ocp_int", + "hphl_ocp_det", + "ear_cnp_int", + "hphr_cnp_int", + "hphl_cnp_int"; + + cdc-vdda-cp-supply = <&pm8916_s4>; + qcom,cdc-vdda-cp-voltage = <1800000 2200000>; + qcom,cdc-vdda-cp-current = <770000>; + + cdc-vdd-pa-supply = <&pm8916_l5>; + qcom,cdc-vdd-pa-voltage = <1800000 1800000>; + qcom,cdc-vdd-pa-current = <5000>; + + cdc-vdd-mic-bias-supply = <&pm8916_l13>; + qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>; + qcom,cdc-vdd-mic-bias-current = <25000>; + + qcom,cdc-mclk-clk-rate = <9600000>; + + qcom,cdc-static-supplies = "cdc-vdda-cp", + "cdc-vdd-pa"; + + qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias"; + + msm_digital_codec: msm-dig-codec { + compatible = "qcom,msm-digital-codec"; + reg = <0x0771C000 0x0>; + cdc-vdd-digital-supply = <&pm8916_l5>; + qcom,cdc-vdd-digital-voltage = <1800000 1800000>; + qcom,cdc-vdd-digital-current = <5000>; + qcom,cdc-on-demand-supplies = "cdc-vdd-digital"; + }; + }; +}; + &msm_gpio { sdc2_wlan_gpio_on: sdc2_wlan_gpio_on { mux { @@ -156,8 +292,8 @@ }; &usb_otg { - interrupts = <0 134 0>,<0 140 0>,<0 136 0>; - interrupt-names = "core_irq", "async_irq", "phy_irq"; + interrupts = <0 134 0>,<0 140 0>; + interrupt-names = "core_irq", "async_irq"; qcom,hsusb-otg-mode = <3>; qcom,switch-vbus-w-id; vbus_otg-supply = <&vph_pwr_vreg>; @@ -192,7 +328,7 @@ qcom,recharge-thresh-mv = <100>; qcom,thermal-mitigation = <1500 700 600 0>; regulator-name = "smb1360_otg_vreg"; - status= "disabled"; + status= "okay"; }; }; @@ -221,3 +357,7 @@ &blsp1_uart2_hs { status = "ok"; }; + +&blsp1_uart1 { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts b/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts index 2c6daf12f532..4a625f896d00 100644 --- a/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts +++ b/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts @@ -15,7 +15,6 @@ #include "msm8909-mtp.dtsi" #include "8909-pm8916.dtsi" #include "msm8909-pm8916-mtp.dtsi" -#include "apq8009-audio-external_codec.dtsi" #include "apq8009-memory.dtsi" #include <dt-bindings/pinctrl/qcom,pmic-mpp.h> #include "msm8909-pm8916-camera.dtsi" @@ -29,7 +28,46 @@ }; &audio_codec_mtp { - status = "disabled"; + qcom,model = "msm8909-pm8916-snd-card"; + asoc-codec = <&stub_codec>, <&msm_digital_codec>, + <&pmic_analog_codec>; + asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec", + "analog-codec"; + + qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>; + asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, + <&loopback>, <&compress>, <&hostless>, + <&afe>, <&lsm>, <&routing>, <&lpa>, + <&voice_svc>,<&pcm_noirq>; + + 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-pcm-lpa", + "msm-voice-svc", "msm-pcm-dsp-noirq"; + + asoc-cpu = <&dai_pri_auxpcm>, + <&dai_mi2s0>, <&dai_mi2s1>, <&dai_mi2s2>, + <&dai_mi2s3>, <&dai_mi2s4>, <&dai_mi2s5>, + <&bt_sco_rx>, <&bt_sco_tx>, <&bt_a2dp_rx>, + <&int_fm_rx>, <&int_fm_tx>, <&afe_pcm_rx>, + <&afe_pcm_tx>, <&afe_proxy_rx>, <&afe_proxy_tx>, + <&incall_record_rx>, <&incall_record_tx>, + <&incall_music_rx>, <&incall_music_2_rx>; + + asoc-cpu-names = "msm-dai-q6-auxpcm.1", + "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", + "msm-dai-q6-mi2s.4", "msm-dai-q6-mi2s.6", + "msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289", + "msm-dai-q6-dev.12290", "msm-dai-q6-dev.12292", + "msm-dai-q6-dev.12293", "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"; }; &pm8916_gpios { @@ -94,40 +132,79 @@ }; }; +&spmi_bus { + pm8916@1 { + pmic_analog_codec: analog-codec@f000 { + status = "okay"; + compatible = "qcom,pmic-analog-codec"; + reg = <0xf000 0x200>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-parent = <&spmi_bus>; + interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>, + <0x1 0xf0 0x1 IRQ_TYPE_NONE>, + <0x1 0xf0 0x2 IRQ_TYPE_NONE>, + <0x1 0xf0 0x3 IRQ_TYPE_NONE>, + <0x1 0xf0 0x4 IRQ_TYPE_NONE>, + <0x1 0xf0 0x5 IRQ_TYPE_NONE>, + <0x1 0xf0 0x6 IRQ_TYPE_NONE>, + <0x1 0xf0 0x7 IRQ_TYPE_NONE>, + <0x1 0xf1 0x0 IRQ_TYPE_NONE>, + <0x1 0xf1 0x1 IRQ_TYPE_NONE>, + <0x1 0xf1 0x2 IRQ_TYPE_NONE>, + <0x1 0xf1 0x3 IRQ_TYPE_NONE>, + <0x1 0xf1 0x4 IRQ_TYPE_NONE>, + <0x1 0xf1 0x5 IRQ_TYPE_NONE>; + interrupt-names = "spk_cnp_int", + "spk_clip_int", + "spk_ocp_int", + "ins_rem_det1", + "but_rel_det", + "but_press_det", + "ins_rem_det", + "mbhc_int", + "ear_ocp_int", + "hphr_ocp_int", + "hphl_ocp_det", + "ear_cnp_int", + "hphr_cnp_int", + "hphl_cnp_int"; + + cdc-vdda-cp-supply = <&pm8916_s4>; + qcom,cdc-vdda-cp-voltage = <1800000 2100000>; + qcom,cdc-vdda-cp-current = <1800000>; + + cdc-vdd-io-supply = <&pm8916_l5>; + qcom,cdc-vdd-io-voltage = <1800000 1800000>; + qcom,cdc-vdd-io-current = <5000>; + + cdc-vdd-pa-supply = <&pm8916_s4>; + qcom,cdc-vdd-pa-voltage = <1800000 2100000>; + qcom,cdc-vdd-pa-current = <1800000>; + + cdc-vdd-mic-bias-supply = <&pm8916_l13>; + qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>; + qcom,cdc-vdd-mic-bias-current = <5000>; + + qcom,cdc-mclk-clk-rate = <9600000>; + + qcom,cdc-static-supplies = "cdc-vdd-io", + "cdc-vdd-pa", + "cdc-vdda-cp"; + + qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias"; + + msm_digital_codec: msm-dig-codec { + compatible = "qcom,msm-digital-codec"; + reg = <0x0771c000 0x0>; + }; + }; + }; +}; + &soc { ext_codec: sound-9335 { - qcom,audio-routing = - "AIF4 VI", "MCLK", - "RX_BIAS", "MCLK", - "MADINPUT", "MCLK", - "AMIC2", "MIC BIAS2", - "MIC BIAS2", "Headset Mic", - "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", - "SpkrLeft IN", "SPK1 OUT", - "SpkrRight IN", "SPK2 OUT"; - - qcom,msm-gpios = - "us_eu_gpio"; - qcom,pinctrl-names = - "all_off", - "us_eu_gpio_act"; - pinctrl-names = - "all_off", - "us_eu_gpio_act"; - pinctrl-0 = <&cross_conn_det_sus>; - pinctrl-1 = <&cross_conn_det_act>; - qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>; - qcom,quat-mi2s-gpios = <&cdc_quat_mi2s_gpios>; - - qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight", - "SpkrLeft", "SpkrRight"; + status = "disabled"; }; i2c@78b9000 { @@ -211,32 +288,15 @@ i2c@78b8000 { wcd9xxx_codec@d { - status = "okay"; - qcom,wcd-rst-gpio-node = <&wcd_rst_gpio>; + status = "disabled"; }; }; cdc_pri_mi2s_gpios: msm_cdc_pinctrl_pri { compatible = "qcom,msm-cdc-pinctrl"; pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&pri_mi2s_active &pri_mi2s_ws_active - &pri_mi2s_dout_active &pri_mi2s_din_active>; - pinctrl-1 = <&pri_mi2s_sleep &pri_mi2s_ws_sleep - &pri_mi2s_dout_sleep &pri_mi2s_din_sleep>; - }; - - cdc_quat_mi2s_gpios: msm_cdc_pinctrl_quat { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&quat_mi2s_active &quat_mi2s_din_active>; - pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_din_sleep>; - }; - - wcd_rst_gpio: wcd_gpio_ctrl { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&cdc_reset_active>; - pinctrl-1 = <&cdc_reset_sleep>; + pinctrl-0 = <&cdc_pdm_lines_act>; + pinctrl-1 = <&cdc_pdm_lines_sus>; }; }; @@ -362,14 +422,6 @@ status = "disabled"; }; -&wcd_rst_gpio { - status = "okay"; -}; - -&ext_codec { - status = "okay"; -}; - &blsp1_uart2_hs { status = "disabled"; }; diff --git a/arch/arm64/boot/dts/qcom/apq8009-robot-rome-refboard.dts b/arch/arm64/boot/dts/qcom/apq8009-robot-rome-refboard.dts index 467744809317..0938d8645cae 100644 --- a/arch/arm64/boot/dts/qcom/apq8009-robot-rome-refboard.dts +++ b/arch/arm64/boot/dts/qcom/apq8009-robot-rome-refboard.dts @@ -15,7 +15,6 @@ #include "msm8909-mtp.dtsi" #include "8909-pm8916.dtsi" #include "msm8909-pm8916-mtp.dtsi" -#include "apq8009-audio-external_codec.dtsi" #include "apq8009-memory.dtsi" #include <dt-bindings/pinctrl/qcom,pmic-mpp.h> #include "msm8909-pm8916-camera.dtsi" @@ -29,7 +28,43 @@ }; &audio_codec_mtp { - status = "disabled"; + qcom,model = "msm8909-pm8916-snd-card"; + asoc-codec = <&stub_codec>, <&msm_digital_codec>, + <&pmic_analog_codec>; + asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec", + "analog-codec"; + + qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>; + asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, + <&loopback>, <&compress>, <&hostless>, + <&afe>, <&lsm>, <&routing>, <&lpa>, + <&voice_svc>,<&pcm_noirq>; + 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-pcm-lpa", + "msm-voice-svc","msm-pcm-dsp-noirq"; + asoc-cpu = <&dai_pri_auxpcm>, + <&dai_mi2s0>, <&dai_mi2s1>, <&dai_mi2s2>, + <&dai_mi2s3>, <&dai_mi2s4>, <&dai_mi2s5>, + <&bt_sco_rx>, <&bt_sco_tx>, <&bt_a2dp_rx>, + <&int_fm_rx>, <&int_fm_tx>, <&afe_pcm_rx>, + <&afe_pcm_tx>, <&afe_proxy_rx>, <&afe_proxy_tx>, + <&incall_record_rx>, <&incall_record_tx>, + <&incall_music_rx>, <&incall_music_2_rx>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", + "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", + "msm-dai-q6-mi2s.4", "msm-dai-q6-mi2s.6", + "msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289", + "msm-dai-q6-dev.12290", "msm-dai-q6-dev.12292", + "msm-dai-q6-dev.12293", "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"; }; &pm8916_gpios { @@ -93,41 +128,79 @@ }; }; }; +&spmi_bus { + pm8916@1 { + pmic_analog_codec: analog-codec@f000 { + status = "okay"; + compatible = "qcom,pmic-analog-codec"; + reg = <0xf000 0x200>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-parent = <&spmi_bus>; + interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>, + <0x1 0xf0 0x1 IRQ_TYPE_NONE>, + <0x1 0xf0 0x2 IRQ_TYPE_NONE>, + <0x1 0xf0 0x3 IRQ_TYPE_NONE>, + <0x1 0xf0 0x4 IRQ_TYPE_NONE>, + <0x1 0xf0 0x5 IRQ_TYPE_NONE>, + <0x1 0xf0 0x6 IRQ_TYPE_NONE>, + <0x1 0xf0 0x7 IRQ_TYPE_NONE>, + <0x1 0xf1 0x0 IRQ_TYPE_NONE>, + <0x1 0xf1 0x1 IRQ_TYPE_NONE>, + <0x1 0xf1 0x2 IRQ_TYPE_NONE>, + <0x1 0xf1 0x3 IRQ_TYPE_NONE>, + <0x1 0xf1 0x4 IRQ_TYPE_NONE>, + <0x1 0xf1 0x5 IRQ_TYPE_NONE>; + interrupt-names = "spk_cnp_int", + "spk_clip_int", + "spk_ocp_int", + "ins_rem_det1", + "but_rel_det", + "but_press_det", + "ins_rem_det", + "mbhc_int", + "ear_ocp_int", + "hphr_ocp_int", + "hphl_ocp_det", + "ear_cnp_int", + "hphr_cnp_int", + "hphl_cnp_int"; + + cdc-vdda-cp-supply = <&pm8916_s4>; + qcom,cdc-vdda-cp-voltage = <1800000 2100000>; + qcom,cdc-vdda-cp-current = <1800000>; + + cdc-vdd-io-supply = <&pm8916_l5>; + qcom,cdc-vdd-io-voltage = <1800000 1800000>; + qcom,cdc-vdd-io-current = <5000>; + + cdc-vdd-pa-supply = <&pm8916_s4>; + qcom,cdc-vdd-pa-voltage = <1800000 2100000>; + qcom,cdc-vdd-pa-current = <1800000>; + + cdc-vdd-mic-bias-supply = <&pm8916_l13>; + qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>; + qcom,cdc-vdd-mic-bias-current = <5000>; + + qcom,cdc-mclk-clk-rate = <9600000>; + + qcom,cdc-static-supplies = "cdc-vdd-io", + "cdc-vdd-pa", + "cdc-vdda-cp"; + + qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias"; + + msm_digital_codec: msm-dig-codec { + compatible = "qcom,msm-digital-codec"; + reg = <0x0771c000 0x0>; + }; + }; + }; +}; &soc { ext_codec: sound-9335 { - qcom,audio-routing = - "AIF4 VI", "MCLK", - "RX_BIAS", "MCLK", - "MADINPUT", "MCLK", - "AMIC2", "MIC BIAS2", - "MIC BIAS2", "Headset Mic", - "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", - "SpkrLeft IN", "SPK1 OUT", - "SpkrRight IN", "SPK2 OUT"; - - qcom,msm-gpios = - "us_eu_gpio"; - qcom,pinctrl-names = - "all_off", - "us_eu_gpio_act"; - pinctrl-names = - "all_off", - "us_eu_gpio_act"; - pinctrl-0 = <&cross_conn_det_sus>; - pinctrl-1 = <&cross_conn_det_act>; - qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>; - qcom,quat-mi2s-gpios = <&cdc_quat_mi2s_gpios>; - - qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight", - "SpkrLeft", "SpkrRight"; + status = "disabled"; }; i2c@78b9000 { @@ -210,32 +283,15 @@ i2c@78b8000 { wcd9xxx_codec@d { - status = "okay"; - qcom,wcd-rst-gpio-node = <&wcd_rst_gpio>; + status = "disabled"; }; }; cdc_pri_mi2s_gpios: msm_cdc_pinctrl_pri { compatible = "qcom,msm-cdc-pinctrl"; pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&pri_mi2s_active &pri_mi2s_ws_active - &pri_mi2s_dout_active &pri_mi2s_din_active>; - pinctrl-1 = <&pri_mi2s_sleep &pri_mi2s_ws_sleep - &pri_mi2s_dout_sleep &pri_mi2s_din_sleep>; - }; - - cdc_quat_mi2s_gpios: msm_cdc_pinctrl_quat { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&quat_mi2s_active &quat_mi2s_din_active>; - pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_din_sleep>; - }; - - wcd_rst_gpio: wcd_gpio_ctrl { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&cdc_reset_active>; - pinctrl-1 = <&cdc_reset_sleep>; + pinctrl-0 = <&cdc_pdm_lines_act>; + pinctrl-1 = <&cdc_pdm_lines_sus>; }; }; @@ -365,16 +421,8 @@ status = "disabled"; }; -&wcd_rst_gpio { - status = "okay"; -}; - -&ext_codec { - status = "okay"; -}; - &blsp1_uart2_hs { - status = "okay"; + status= "okay"; }; /delete-node/ &cont_splash_mem; diff --git a/arch/arm64/boot/dts/qcom/msm8909-audio-bg_codec.dtsi b/arch/arm64/boot/dts/qcom/msm8909-audio-bg_codec.dtsi index fa6498edcd7d..ae3900efd393 100644 --- a/arch/arm64/boot/dts/qcom/msm8909-audio-bg_codec.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8909-audio-bg_codec.dtsi @@ -50,7 +50,7 @@ "msm-voice-svc"; asoc-cpu = <&dai_pri_auxpcm>, <&dai_mi2s0>, <&dai_mi2s1>, <&dai_mi2s2>, - <&dai_mi2s3>, <&dai_mi2s5>, <&dai_mi2s6>, + <&dai_mi2s3>, <&dai_mi2s4>, <&dai_mi2s5>, <&bt_sco_rx>, <&bt_sco_tx>, <&bt_a2dp_rx>, <&int_fm_rx>, <&int_fm_tx>, <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>, <&afe_proxy_tx>, @@ -63,7 +63,7 @@ asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", - "msm-dai-q6-mi2s.5", "msm-dai-q6-mi2s.6", + "msm-dai-q6-mi2s.4", "msm-dai-q6-mi2s.6", "msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289", "msm-dai-q6-dev.12290", "msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293", "msm-dai-q6-dev.224", diff --git a/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi index ee2d0ac9e7a8..484488628871 100644 --- a/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi @@ -211,7 +211,7 @@ "msm-voice-svc"; asoc-cpu = <&dai_pri_auxpcm>, <&dai_mi2s0>, <&dai_mi2s1>, <&dai_mi2s2>, - <&dai_mi2s3>, <&dai_mi2s5>, <&dai_mi2s6>, + <&dai_mi2s3>, <&dai_mi2s4>, <&dai_mi2s5>, <&bt_sco_rx>, <&bt_sco_tx>, <&bt_a2dp_rx>, <&int_fm_rx>, <&int_fm_tx>, <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>, <&afe_proxy_tx>, @@ -220,7 +220,7 @@ asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", - "msm-dai-q6-mi2s.5", "msm-dai-q6-mi2s.6", + "msm-dai-q6-mi2s.4", "msm-dai-q6-mi2s.6", "msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289", "msm-dai-q6-dev.12290", "msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293", "msm-dai-q6-dev.224", diff --git a/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi index c69e69961146..3bf23de715b1 100644 --- a/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi @@ -1981,7 +1981,7 @@ config { pins = "gpio4"; drive-strength = <8>; - bias-pull-none; + output-high; }; }; @@ -1995,6 +1995,7 @@ pins = "gpio4"; drive-strength = <2>; bias-disable; + output-low; }; }; @@ -2007,7 +2008,7 @@ config { pins = "gpio5"; drive-strength = <8>; - bias-pull-none; + input-enable; }; }; @@ -2084,6 +2085,62 @@ }; }; + amp_mute { + label = "amp_mute"; + amp_mute_active: amp_mute_active { + mux { + pins = "gpio84"; + function = "gpio"; + }; + config { + pins = "gpio84"; + drive-strength = <8>; /* 8 MA */ + bias-pull-up; /* PULL UP */ + output-high; + }; + }; + + amp_mute_sleep: amp_mute_sleep { + mux { + pins = "gpio84"; + function = "gpio"; + }; + configs { + pins = "gpio84"; + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + }; + + ext_amp_ctrl { + label = "ext_amp_ctrl"; + ext_amp_ctrl_active: ext_amp_ctrl_active { + mux { + pins = "gpio25"; + function = "gpio"; + }; + config { + pins = "gpio25"; + drive-strength = <8>; /* 8 MA */ + bias-pull-up; /* PULL UP */ + output-high; + }; + }; + + ext_amp_ctrl_sleep: ext_amp_ctrl_sleep { + mux { + pins = "gpio25"; + function = "gpio"; + }; + configs { + pins = "gpio25"; + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + }; + pmx_i2s_mclk { label = "i2s_mclk"; i2s_mclk_active: i2s_mclk_active { diff --git a/arch/arm64/boot/dts/qcom/msm8909.dtsi b/arch/arm64/boot/dts/qcom/msm8909.dtsi index 8c06c93783fa..cb5667ff14e1 100644 --- a/arch/arm64/boot/dts/qcom/msm8909.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8909.dtsi @@ -139,6 +139,10 @@ firmware: firmware { android { compatible = "android,firmware"; + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,boot,system,vendor,recovery"; + }; fstab { compatible = "android,fstab"; vendor_fstab: vendor { @@ -147,7 +151,7 @@ "/dev/block/platform/soc/7824900.sdhci/by-name/vendor"; type = "ext4"; mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait,verify"; + fsmgr_flags = "wait,avb"; status = "ok"; }; system_fstab: system { @@ -156,7 +160,7 @@ "/dev/block/platform/soc/7824900.sdhci/by-name/system"; type = "ext4"; mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait,verify"; + fsmgr_flags = "wait,avb"; status = "ok"; }; }; @@ -1421,6 +1425,12 @@ qcom,latency-level = "ultra"; }; + pcm_noirq: qcom,msm-pcm-dsp-noirq { + compatible = "qcom,msm-pcm-dsp-noirq"; + qcom,msm-pcm-low-latency; + qcom,latency-level = "ultra"; + }; + lpa: qcom,msm-pcm-lpa { compatible = "qcom,msm-pcm-lpa"; }; @@ -1459,6 +1469,12 @@ compatible = "qcom,msm-pcm-loopback"; }; + pcm_noirq: qcom,msm-pcm-dsp-noirq { + compatible = "qcom,msm-pcm-dsp-noirq"; + qcom,msm-pcm-low-latency; + qcom,latency-level = "ultra"; + }; + qcom,msm-dai-mi2s { compatible = "qcom,msm-dai-mi2s"; dai_mi2s0: qcom,msm-dai-q6-mi2s-prim { @@ -1475,6 +1491,13 @@ qcom,msm-mi2s-tx-lines = <0>; }; + dai_mi2s2: qcom,msm-dai-q6-mi2s-tert { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <2>; + qcom,msm-mi2s-rx-lines = <0>; + qcom,msm-mi2s-tx-lines = <3>; + }; + dai_mi2s3: qcom,msm-dai-q6-mi2s-quat { compatible = "qcom,msm-dai-q6-mi2s"; qcom,msm-dai-q6-mi2s-dev-id = <3>; @@ -1482,21 +1505,14 @@ qcom,msm-mi2s-tx-lines = <3>; }; - dai_mi2s5: qcom,msm-dai-q6-mi2s-quin { + dai_mi2s4: qcom,msm-dai-q6-mi2s-quin { compatible = "qcom,msm-dai-q6-mi2s"; - qcom,msm-dai-q6-mi2s-dev-id = <5>; + qcom,msm-dai-q6-mi2s-dev-id = <4>; qcom,msm-mi2s-rx-lines = <1>; qcom,msm-mi2s-tx-lines = <2>; }; - dai_mi2s2: qcom,msm-dai-q6-mi2s-tert { - compatible = "qcom,msm-dai-q6-mi2s"; - qcom,msm-dai-q6-mi2s-dev-id = <2>; - qcom,msm-mi2s-rx-lines = <0>; - qcom,msm-mi2s-tx-lines = <3>; - }; - - dai_mi2s6: qcom,msm-dai-q6-mi2s-senary { + dai_mi2s5: qcom,msm-dai-q6-mi2s-senary { compatible = "qcom,msm-dai-q6-mi2s"; qcom,msm-dai-q6-mi2s-dev-id = <6>; qcom,msm-mi2s-rx-lines = <0>; @@ -1647,6 +1663,13 @@ compatible = "qcom,msm-audio-ion"; }; + qcom,msm-audio-apr { + compatible = "qcom,msm-audio-apr"; + msm_audio_apr_dummy { + compatible = "qcom,msm-audio-apr-dummy"; + }; + }; + qcom,mdsprpc-mem { compatible = "qcom,msm-mdsprpc-mem-region"; memory-region = <&adsp_mem>; diff --git a/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi b/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi index e64af14bde3a..e599b31bb215 100644 --- a/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi @@ -1083,7 +1083,7 @@ modem_etm0 { compatible = "qcom,coresight-remote-etm"; coresight-name = "coresight-modem-etm0"; - qcom,inst-id = <11>; + qcom,inst-id = <2>; port { modem_etm0_out_funnel_right: endpoint { diff --git a/arch/arm64/boot/dts/qcom/msm8937.dtsi b/arch/arm64/boot/dts/qcom/msm8937.dtsi index 1c13051a7897..b440cb60c1d7 100644 --- a/arch/arm64/boot/dts/qcom/msm8937.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8937.dtsi @@ -914,7 +914,6 @@ qcom,vdd-voltage-level = <0 1200000 1200000>; vbus_otg-supply = <&smbcharger_charger_otg>; - qcom,hsusb-otg-phy-init-seq = <0x06 0x82 0xffffffff>; qcom,hsusb-otg-phy-type = <3>; /* SNPS Femto PHY */ qcom,hsusb-otg-mode = <3>; /* OTG mode */ qcom,hsusb-otg-otg-control = <2>; /* PMIC */ diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi index d175b8099df1..93516a1fd7cf 100644 --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi @@ -638,6 +638,13 @@ regulator-min-microvolt = <4000000>; regulator-max-microvolt = <6000000>; }; + + lcdb_bst_vreg: bst { + label = "bst"; + regulator-name = "lcdb_bst"; + regulator-min-microvolt = <4700000>; + regulator-max-microvolt = <6275000>; + }; }; flash_led: qcom,leds@d300 { diff --git a/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi b/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi index f5f3b3c4305f..0d47ba61fb99 100644 --- a/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi @@ -138,15 +138,13 @@ }; }; -&soc { - qcom,dsi-display@17 { - qcom,dsi-display-active; +&ext_dsi_bridge_display { + qcom,dsi-display-active; - ports { - port@0 { - endpoint { - remote-endpoint = <<9611_in>; - }; + ports { + port@0 { + endpoint { + remote-endpoint = <<9611_in>; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/sdm439.dtsi b/arch/arm64/boot/dts/qcom/sdm439.dtsi index ef8ea1f30642..ef22440ca923 100644 --- a/arch/arm64/boot/dts/qcom/sdm439.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm439.dtsi @@ -661,3 +661,7 @@ }; }; }; + +&usb_otg { + qcom,hsusb-otg-phy-init-seq = <0x06 0x82 0xffffffff>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi index bb07c045906b..5c40ecc92e38 100644 --- a/arch/arm64/boot/dts/qcom/sdm670.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi @@ -1875,7 +1875,7 @@ ufs-qcom-crypto = <&ufs_ice>; lanes-per-direction = <1>; - spm-level = <5>; + dev-ref-clk-freq = <0>; /* 19.2 MHz */ clock-names = diff --git a/arch/arm64/boot/dts/qcom/sxr1130-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/sxr1130-qrd-overlay.dts new file mode 100644 index 000000000000..d5f2a3ee084d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sxr1130-qrd-overlay.dts @@ -0,0 +1,32 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/clock/qcom,gcc-sdm845.h> +#include <dt-bindings/clock/qcom,camcc-sdm845.h> +#include <dt-bindings/clock/qcom,dispcc-sdm845.h> +#include <dt-bindings/clock/qcom,rpmh.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +#include "sxr1130-qrd.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SXR1130 PM660 + PM660L QRD"; + compatible = "qcom,sxr1130-qrd", "qcom,sxr1130", "qcom,qrd"; + qcom,msm-id = <371 0x0>; + qcom,board-id = <0x0003000b 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0102001a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; +}; diff --git a/arch/arm64/boot/dts/qcom/sxr1130-qrd.dts b/arch/arm64/boot/dts/qcom/sxr1130-qrd.dts new file mode 100644 index 000000000000..dd9db959b619 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sxr1130-qrd.dts @@ -0,0 +1,26 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * 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 "sxr1130.dtsi" +#include "sxr1130-qrd.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SXR1130 PM660 + PM660L QRD"; + compatible = "qcom,sxr1130-qrd", "qcom,sxr1130", "qcom,qrd"; + qcom,board-id = <0x0003000b 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0102001a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; +}; diff --git a/arch/arm64/boot/dts/qcom/sxr1130-qrd.dtsi b/arch/arm64/boot/dts/qcom/sxr1130-qrd.dtsi new file mode 100644 index 000000000000..3d25629c84c4 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sxr1130-qrd.dtsi @@ -0,0 +1,13 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "sdm670-qrd-sku1.dtsi" diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index a3c19c4a6e5c..41ab3386f138 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -336,12 +336,13 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last) int header_len = sizeof(struct diag_ctrl_msg_mask); uint8_t *buf = NULL, *temp = NULL; uint8_t upd = 0; - uint8_t msg_mask_tbl_count_local; + uint8_t msg_mask_tbl_count_local = 0; uint32_t mask_size = 0, pd_mask = 0; struct diag_mask_info *mask_info = NULL; struct diag_msg_mask_t *mask = NULL; struct diag_ctrl_msg_mask header; struct diagfwd_info *fwd_info = NULL; + struct diag_md_session_t *md_session_info = NULL; if (peripheral >= NUM_PERIPHERALS) return; @@ -357,14 +358,19 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last) if (driver->md_session_mask != 0) { if (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)) { - if (driver->md_session_map[peripheral]) + if (driver->md_session_map[peripheral]) { mask_info = driver->md_session_map[peripheral]->msg_mask; + md_session_info = + driver->md_session_map[peripheral]; + } } else if (driver->md_session_mask & pd_mask) { upd = diag_mask_to_pd_value(driver->md_session_mask); - if (upd && driver->md_session_map[upd]) + if (upd && driver->md_session_map[upd]) { mask_info = driver->md_session_map[upd]->msg_mask; + md_session_info = driver->md_session_map[upd]; + } } else { DIAG_LOG(DIAG_DEBUG_MASKS, "asking for mask update with unknown session mask\n"); @@ -383,7 +389,10 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last) return; } buf = mask_info->update_buf; - msg_mask_tbl_count_local = driver->msg_mask_tbl_count; + if (md_session_info) + msg_mask_tbl_count_local = md_session_info->msg_mask_tbl_count; + else + msg_mask_tbl_count_local = driver->msg_mask_tbl_count; mutex_unlock(&driver->msg_mask_lock); mutex_lock(&mask_info->lock); switch (mask_info->status) { @@ -565,6 +574,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, { int i; int write_len = 0; + uint8_t msg_mask_tbl_count = 0; struct diag_msg_mask_t *mask_ptr = NULL; struct diag_msg_ssid_query_t rsp; struct diag_ssid_range_t ssid_range; @@ -594,15 +604,17 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, return 0; } mutex_lock(&driver->msg_mask_lock); + msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; rsp.cmd_code = DIAG_CMD_MSG_CONFIG; rsp.sub_cmd = DIAG_CMD_OP_GET_SSID_RANGE; rsp.status = MSG_STATUS_SUCCESS; rsp.padding = 0; - rsp.count = driver->msg_mask_tbl_count; + rsp.count = msg_mask_tbl_count; memcpy(dest_buf, &rsp, sizeof(rsp)); write_len += sizeof(rsp); mask_ptr = (struct diag_msg_mask_t *)mask_info->ptr; - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask_ptr++) { + for (i = 0; i < msg_mask_tbl_count; i++, mask_ptr++) { if (write_len + sizeof(ssid_range) > dest_len) { pr_err("diag: In %s, Truncating response due to size limitations of rsp buffer\n", __func__); @@ -679,6 +691,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, int i; int write_len = 0; uint32_t mask_size = 0; + uint8_t msg_mask_tbl_count = 0; struct diag_msg_mask_t *mask = NULL; struct diag_build_mask_req_t *req = NULL; struct diag_msg_build_mask_t rsp; @@ -709,6 +722,8 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, } mutex_lock(&driver->msg_mask_lock); + msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; req = (struct diag_build_mask_req_t *)src_buf; rsp.cmd_code = DIAG_CMD_MSG_CONFIG; rsp.sub_cmd = DIAG_CMD_OP_GET_MSG_MASK; @@ -724,7 +739,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, mutex_unlock(&driver->md_session_lock); return -EINVAL; } - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + for (i = 0; i < msg_mask_tbl_count; i++, mask++) { if (!mask->ptr) continue; if ((req->ssid_first < mask->ssid_first) || @@ -760,6 +775,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, struct diag_mask_info *mask_info = NULL; struct diag_msg_mask_t *mask_next = NULL; struct diag_md_session_t *info = NULL; + uint8_t msg_mask_tbl_count = 0; mutex_lock(&driver->md_session_lock); info = diag_md_session_get_pid(pid); @@ -792,10 +808,13 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, mutex_unlock(&driver->md_session_lock); return -EINVAL; } - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + + msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; + for (i = 0; i < msg_mask_tbl_count; i++, mask++) { if (!mask->ptr) continue; - if (i < (driver->msg_mask_tbl_count - 1)) { + if (i < (msg_mask_tbl_count - 1)) { mask_next = mask; mask_next++; } else @@ -905,6 +924,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_mask_t *mask = NULL; struct diag_mask_info *mask_info = NULL; struct diag_md_session_t *info = NULL; + uint8_t msg_mask_tbl_count = 0; mutex_lock(&driver->md_session_lock); info = diag_md_session_get_pid(pid); @@ -939,9 +959,11 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, mutex_unlock(&driver->md_session_lock); return -EINVAL; } + msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; mask_info->status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED : DIAG_CTRL_MASK_ALL_DISABLED; - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + for (i = 0; i < msg_mask_tbl_count; i++, mask++) { if (mask && mask->ptr) { mutex_lock(&mask->lock); memset(mask->ptr, req->rt_mask, @@ -1755,7 +1777,6 @@ static int __diag_mask_init(struct diag_mask_info *mask_info, int mask_len, } kmemleak_not_leak(mask_info->update_buf); } - mutex_init(&mask_info->lock); return 0; } @@ -1778,9 +1799,10 @@ int diag_log_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src) struct diag_log_mask_t *src_mask = NULL; struct diag_log_mask_t *dest_mask = NULL; - if (!src) + if (!src || !dest) return -EINVAL; + mutex_init(&dest->lock); err = __diag_mask_init(dest, LOG_MASK_SIZE, APPS_BUF_SIZE); if (err) return err; @@ -1842,9 +1864,11 @@ static int diag_msg_mask_init(void) { int err = 0, i; + mutex_init(&msg_mask.lock); err = __diag_mask_init(&msg_mask, MSG_MASK_SIZE, APPS_BUF_SIZE); if (err) return err; + err = diag_create_msg_mask_table(); if (err) { pr_err("diag: Unable to create msg masks, err: %d\n", err); @@ -1859,7 +1883,8 @@ static int diag_msg_mask_init(void) return 0; } -int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src) +int diag_msg_mask_copy(struct diag_md_session_t *new_session, + struct diag_mask_info *dest, struct diag_mask_info *src) { int i, err = 0, mask_size = 0; struct diag_msg_mask_t *src_mask = NULL; @@ -1869,17 +1894,25 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src) if (!src || !dest) return -EINVAL; - err = __diag_mask_init(dest, MSG_MASK_SIZE, APPS_BUF_SIZE); - if (err) - return err; + mutex_init(&dest->lock); mutex_lock(&dest->lock); mutex_lock(&driver->msg_mask_lock); + new_session->msg_mask_tbl_count = + driver->msg_mask_tbl_count; + err = __diag_mask_init(dest, + (new_session->msg_mask_tbl_count * + sizeof(struct diag_msg_mask_t)), APPS_BUF_SIZE); + if (err) { + mutex_unlock(&driver->msg_mask_lock); + mutex_unlock(&dest->lock); + return err; + } src_mask = (struct diag_msg_mask_t *)src->ptr; dest_mask = (struct diag_msg_mask_t *)dest->ptr; dest->mask_len = src->mask_len; dest->status = src->status; - for (i = 0; i < driver->msg_mask_tbl_count; i++) { + for (i = 0; i < new_session->msg_mask_tbl_count; i++) { range.ssid_first = src_mask->ssid_first; range.ssid_last = src_mask->ssid_last; err = diag_create_msg_mask_table_entry(dest_mask, &range); @@ -1898,10 +1931,12 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src) return err; } -void diag_msg_mask_free(struct diag_mask_info *mask_info) +void diag_msg_mask_free(struct diag_mask_info *mask_info, + struct diag_md_session_t *session_info) { int i; struct diag_msg_mask_t *mask = NULL; + uint8_t msg_mask_tbl_count = 0; if (!mask_info || !mask_info->ptr) return; @@ -1915,7 +1950,10 @@ void diag_msg_mask_free(struct diag_mask_info *mask_info) mutex_unlock(&mask_info->lock); return; } - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + msg_mask_tbl_count = (session_info) ? + session_info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; + for (i = 0; i < msg_mask_tbl_count; i++, mask++) { kfree(mask->ptr); mask->ptr = NULL; } @@ -1946,6 +1984,7 @@ static int diag_build_time_mask_init(void) int err = 0; /* There is no need for update buffer for Build Time masks */ + mutex_init(&msg_bt_mask.lock); err = __diag_mask_init(&msg_bt_mask, MSG_MASK_SIZE, 0); if (err) return err; @@ -1978,6 +2017,7 @@ static int diag_log_mask_init(void) { int err = 0, i; + mutex_init(&log_mask.lock); err = __diag_mask_init(&log_mask, LOG_MASK_SIZE, APPS_BUF_SIZE); if (err) return err; @@ -2011,6 +2051,7 @@ static int diag_event_mask_init(void) { int err = 0, i; + mutex_init(&event_mask.lock); err = __diag_mask_init(&event_mask, EVENT_MASK_SIZE, APPS_BUF_SIZE); if (err) return err; @@ -2032,6 +2073,7 @@ int diag_event_mask_copy(struct diag_mask_info *dest, if (!src || !dest) return -EINVAL; + mutex_init(&dest->lock); err = __diag_mask_init(dest, EVENT_MASK_SIZE, APPS_BUF_SIZE); if (err) return err; @@ -2068,6 +2110,7 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count, struct diag_mask_info *mask_info = NULL; struct diag_msg_mask_t *mask = NULL; unsigned char *ptr = NULL; + uint8_t msg_mask_tbl_count = 0; if (!buf || count == 0) return -EINVAL; @@ -2092,7 +2135,10 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count, mutex_unlock(&mask_info->lock); return -EINVAL; } - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + + msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; + for (i = 0; i < msg_mask_tbl_count; i++, mask++) { if (!mask->ptr) continue; ptr = mask_info->update_buf; diff --git a/drivers/char/diag/diag_masks.h b/drivers/char/diag/diag_masks.h index 6edeee954d74..a736ff269e8d 100644 --- a/drivers/char/diag/diag_masks.h +++ b/drivers/char/diag/diag_masks.h @@ -160,12 +160,13 @@ int diag_masks_init(void); void diag_masks_exit(void); int diag_log_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src); -int diag_msg_mask_copy(struct diag_mask_info *dest, - struct diag_mask_info *src); +int diag_msg_mask_copy(struct diag_md_session_t *new_session, + struct diag_mask_info *dest, struct diag_mask_info *src); int diag_event_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src); void diag_log_mask_free(struct diag_mask_info *mask_info); -void diag_msg_mask_free(struct diag_mask_info *mask_info); +void diag_msg_mask_free(struct diag_mask_info *mask_info, + struct diag_md_session_t *session_info); void diag_event_mask_free(struct diag_mask_info *mask_info); int diag_process_apps_masks(unsigned char *buf, int len, int pid); void diag_send_updates_peripheral(uint8_t peripheral); diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h index 9bbfb82fec13..f63d78c32b6e 100644 --- a/drivers/char/diag/diagchar.h +++ b/drivers/char/diag/diagchar.h @@ -483,6 +483,7 @@ struct diag_md_session_t { int pid; int peripheral_mask; uint8_t hdlc_disabled; + uint8_t msg_mask_tbl_count; struct timer_list hdlc_reset_timer; struct diag_mask_info *msg_mask; struct diag_mask_info *log_mask; diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 8b089eb6c850..131a050c7f1a 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -1264,7 +1264,8 @@ static void diag_md_session_exit(void) diag_log_mask_free(session_info->log_mask); kfree(session_info->log_mask); session_info->log_mask = NULL; - diag_msg_mask_free(session_info->msg_mask); + diag_msg_mask_free(session_info->msg_mask, + session_info); kfree(session_info->msg_mask); session_info->msg_mask = NULL; diag_event_mask_free(session_info->event_mask); @@ -1335,7 +1336,9 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc) "return value of event copy. err %d\n", err); goto fail_peripheral; } - err = diag_msg_mask_copy(new_session->msg_mask, &msg_mask); + new_session->msg_mask_tbl_count = 0; + err = diag_msg_mask_copy(new_session, new_session->msg_mask, + &msg_mask); if (err) { DIAG_LOG(DIAG_DEBUG_USERSPACE, "return value of msg copy. err %d\n", err); @@ -1371,7 +1374,8 @@ fail_peripheral: diag_event_mask_free(new_session->event_mask); kfree(new_session->event_mask); new_session->event_mask = NULL; - diag_msg_mask_free(new_session->msg_mask); + diag_msg_mask_free(new_session->msg_mask, + new_session); kfree(new_session->msg_mask); new_session->msg_mask = NULL; kfree(new_session); @@ -1399,7 +1403,8 @@ static void diag_md_session_close(int pid) diag_log_mask_free(session_info->log_mask); kfree(session_info->log_mask); session_info->log_mask = NULL; - diag_msg_mask_free(session_info->msg_mask); + diag_msg_mask_free(session_info->msg_mask, + session_info); kfree(session_info->msg_mask); session_info->msg_mask = NULL; diag_event_mask_free(session_info->event_mask); diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c index 2e3828ef11e2..fdaf283f91dc 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c @@ -490,17 +490,24 @@ static int dsi_link_hs_clk_stop(struct dsi_link_hs_clk_info *link_hs_clks) return 0; } -static int dsi_link_lp_clk_start(struct dsi_link_lp_clk_info *link_lp_clks) +static int dsi_link_lp_clk_start(struct dsi_link_lp_clk_info *link_lp_clks, + int index) { int rc = 0; struct dsi_clk_mngr *mngr; struct dsi_link_clks *l_clks; + if (index >= MAX_DSI_CTRL) { + pr_err("Invalid DSI ctrl index\n"); + return -EINVAL; + } + l_clks = container_of(link_lp_clks, struct dsi_link_clks, lp_clks); - mngr = container_of(l_clks, struct dsi_clk_mngr, link_clks[0]); + mngr = container_of(l_clks, struct dsi_clk_mngr, link_clks[index]); if (!mngr) return -EINVAL; + /* * In an ideal world, cont_splash_enabled should not be required inside * the clock manager. But, in the current driver cont_splash_enabled @@ -618,7 +625,7 @@ static int dsi_display_link_clk_enable(struct dsi_link_clks *clks, m_clks = &clks[master_ndx]; if (l_type & DSI_LINK_LP_CLK) { - rc = dsi_link_lp_clk_start(&m_clks->lp_clks); + rc = dsi_link_lp_clk_start(&m_clks->lp_clks, master_ndx); if (rc) { pr_err("failed to turn on master lp link clocks, rc=%d\n", rc); @@ -642,7 +649,7 @@ static int dsi_display_link_clk_enable(struct dsi_link_clks *clks, continue; if (l_type & DSI_LINK_LP_CLK) { - rc = dsi_link_lp_clk_start(&clk->lp_clks); + rc = dsi_link_lp_clk_start(&clk->lp_clks, i); if (rc) { pr_err("failed to turn on lp link clocks, rc=%d\n", rc); @@ -775,13 +782,12 @@ static int dsi_display_link_clk_disable(struct dsi_link_clks *clks, return rc; } -static int dsi_clk_update_link_clk_state(struct dsi_link_clks *l_clks, - enum dsi_lclk_type l_type, u32 l_state, bool enable) +static int dsi_clk_update_link_clk_state(struct dsi_clk_mngr *mngr, + struct dsi_link_clks *l_clks, enum dsi_lclk_type l_type, u32 l_state, + bool enable) { int rc = 0; - struct dsi_clk_mngr *mngr; - mngr = container_of(l_clks, struct dsi_clk_mngr, link_clks[0]); if (!mngr) return -EINVAL; @@ -840,23 +846,13 @@ error: return rc; } -static int dsi_update_clk_state(struct dsi_core_clks *c_clks, u32 c_state, - struct dsi_link_clks *l_clks, u32 l_state) +static int dsi_update_clk_state(struct dsi_clk_mngr *mngr, + struct dsi_core_clks *c_clks, u32 c_state, + struct dsi_link_clks *l_clks, u32 l_state) { int rc = 0; - struct dsi_clk_mngr *mngr; bool l_c_on = false; - if (c_clks) { - mngr = - container_of(c_clks, struct dsi_clk_mngr, core_clks[0]); - } else if (l_clks) { - mngr = - container_of(l_clks, struct dsi_clk_mngr, link_clks[0]); - } else { - mngr = NULL; - } - if (!mngr) return -EINVAL; @@ -898,12 +894,12 @@ static int dsi_update_clk_state(struct dsi_core_clks *c_clks, u32 c_state, if (l_clks) { if (l_state == DSI_CLK_ON) { - rc = dsi_clk_update_link_clk_state(l_clks, + rc = dsi_clk_update_link_clk_state(mngr, l_clks, DSI_LINK_LP_CLK, l_state, true); if (rc) goto error; - rc = dsi_clk_update_link_clk_state(l_clks, + rc = dsi_clk_update_link_clk_state(mngr, l_clks, DSI_LINK_HS_CLK, l_state, true); if (rc) goto error; @@ -947,12 +943,12 @@ static int dsi_update_clk_state(struct dsi_core_clks *c_clks, u32 c_state, pr_debug("ECG: core and Link_on\n"); } - rc = dsi_clk_update_link_clk_state(l_clks, + rc = dsi_clk_update_link_clk_state(mngr, l_clks, DSI_LINK_HS_CLK, l_state, false); if (rc) goto error; - rc = dsi_clk_update_link_clk_state(l_clks, + rc = dsi_clk_update_link_clk_state(mngr, l_clks, DSI_LINK_LP_CLK, l_state, false); if (rc) goto error; @@ -1102,7 +1098,7 @@ static int dsi_recheck_clk_state(struct dsi_clk_mngr *mngr) old_l_clk_state, new_link_clk_state); if (c_clks || l_clks) { - rc = dsi_update_clk_state(c_clks, new_core_clk_state, + rc = dsi_update_clk_state(mngr, c_clks, new_core_clk_state, l_clks, new_link_clk_state); if (rc) { pr_err("failed to update clock state, rc = %d\n", rc); diff --git a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c index 01d2f527d041..96b083839977 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c @@ -287,7 +287,7 @@ int reg_dmav1_init_dspp_op_v4(int feature, enum sde_dspp idx) } if (feature_map[feature] >= REG_DMA_FEATURES_MAX) { - DRM_ERROR("invalid feature map %d for feature %d\n", + DRM_WARN("invalid feature map %d for feature %d\n", feature_map[feature], feature); return -ENOTSUPP; } diff --git a/drivers/gpu/msm/adreno_a6xx_preempt.c b/drivers/gpu/msm/adreno_a6xx_preempt.c index 132fb0231114..89965f2c9b06 100644 --- a/drivers/gpu/msm/adreno_a6xx_preempt.c +++ b/drivers/gpu/msm/adreno_a6xx_preempt.c @@ -232,6 +232,38 @@ static struct adreno_ringbuffer *a6xx_next_ringbuffer( return NULL; } +#define GMU_ACTIVE_STATE_RETRY_MAX 100 + +static int adreno_gmu_wait_for_active(struct adreno_device *adreno_dev) +{ + unsigned int reg, num_retries = 0; + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + + if (!kgsl_gmu_isenabled(device)) + return 0; + + kgsl_gmu_regread(device, + A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE, ®); + + while (reg != GPU_HW_ACTIVE) { + /* Wait for small time before trying again */ + udelay(5); + kgsl_gmu_regread(device, + A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE, ®); + + if (num_retries == GMU_ACTIVE_STATE_RETRY_MAX && + reg != GPU_HW_ACTIVE) { + dev_err(adreno_dev->dev.dev, + "GMU failed to move to ACTIVE state: 0x%x\n", + reg); + return -ETIMEDOUT; + } + num_retries++; + } + + return 0; +} + void a6xx_preemption_trigger(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); @@ -361,6 +393,23 @@ void a6xx_preemption_trigger(struct adreno_device *adreno_dev) upper_32_bits(gpuaddr), FENCE_STATUS_WRITEDROPPED1_MASK); + /* + * Above fence writes will make sure GMU comes out of + * IFPC state if its was in IFPC state but it doesn't + * guarantee that GMU FW actually moved to ACTIVE state + * i.e. wake-up from IFPC is complete. + * Wait for GMU to move to ACTIVE state before triggering + * preemption. This is require to make sure CP doesn't + * interrupt GMU during wake-up from IFPC. + */ + if (adreno_gmu_wait_for_active(adreno_dev)) { + adreno_set_preempt_state(adreno_dev, ADRENO_PREEMPT_NONE); + + adreno_set_gpu_fault(adreno_dev, ADRENO_GMU_FAULT); + adreno_dispatcher_schedule(device); + return; + } + adreno_dev->next_rb = next; /* Start the timer to detect a stuck preemption */ diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index d3bbea3bafe4..eb4c29d535d5 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1397,6 +1397,45 @@ long kgsl_ioctl_device_getproperty(struct kgsl_device_private *dev_priv, kgsl_context_put(context); break; } + case KGSL_PROP_SECURE_BUFFER_ALIGNMENT: + { + unsigned int align; + + if (param->sizebytes != sizeof(unsigned int)) { + result = -EINVAL; + break; + } + /* + * XPUv2 impose the constraint of 1MB memory alignment, + * on the other hand Hypervisor does not have such + * constraints. So driver should fulfill such + * requirements when allocating secure memory. + */ + align = MMU_FEATURE(&dev_priv->device->mmu, + KGSL_MMU_HYP_SECURE_ALLOC) ? PAGE_SIZE : SZ_1M; + + if (copy_to_user(param->value, &align, sizeof(align))) + result = -EFAULT; + + break; + } + case KGSL_PROP_SECURE_CTXT_SUPPORT: + { + unsigned int secure_ctxt; + + if (param->sizebytes != sizeof(unsigned int)) { + result = -EINVAL; + break; + } + + secure_ctxt = dev_priv->device->mmu.secured ? 1 : 0; + + if (copy_to_user(param->value, &secure_ctxt, + sizeof(secure_ctxt))) + result = -EFAULT; + + break; + } default: if (is_compat_task()) result = dev_priv->device->ftbl->getproperty_compat( diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c index b9b1e9c8f4c4..9971fcd4586c 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -2073,16 +2073,16 @@ static u32 etmv4_cross_read(const struct device *dev, u32 offset) coresight_simple_func(struct etmv4_drvdata, etmv4_cross_read, \ name, offset) -coresight_etm4x_simple_func(trcpdcr, TRCPDCR); -coresight_etm4x_simple_func(trcpdsr, TRCPDSR); -coresight_etm4x_simple_func(trclsr, TRCLSR); -coresight_etm4x_simple_func(trcauthstatus, TRCAUTHSTATUS); -coresight_etm4x_simple_func(trcdevid, TRCDEVID); -coresight_etm4x_simple_func(trcdevtype, TRCDEVTYPE); -coresight_etm4x_simple_func(trcpidr0, TRCPIDR0); -coresight_etm4x_simple_func(trcpidr1, TRCPIDR1); -coresight_etm4x_simple_func(trcpidr2, TRCPIDR2); -coresight_etm4x_simple_func(trcpidr3, TRCPIDR3); +coresight_etm4x_cross_read(trcpdcr, TRCPDCR); +coresight_etm4x_cross_read(trcpdsr, TRCPDSR); +coresight_etm4x_cross_read(trclsr, TRCLSR); +coresight_etm4x_cross_read(trcauthstatus, TRCAUTHSTATUS); +coresight_etm4x_cross_read(trcdevid, TRCDEVID); +coresight_etm4x_cross_read(trcdevtype, TRCDEVTYPE); +coresight_etm4x_cross_read(trcpidr0, TRCPIDR0); +coresight_etm4x_cross_read(trcpidr1, TRCPIDR1); +coresight_etm4x_cross_read(trcpidr2, TRCPIDR2); +coresight_etm4x_cross_read(trcpidr3, TRCPIDR3); coresight_etm4x_cross_read(trcoslsr, TRCOSLSR); coresight_etm4x_cross_read(trcconfig, TRCCONFIGR); coresight_etm4x_cross_read(trctraceid, TRCTRACEIDR); diff --git a/drivers/input/misc/qti-haptics.c b/drivers/input/misc/qti-haptics.c index 310eb4162af0..f60e835af89c 100644 --- a/drivers/input/misc/qti-haptics.c +++ b/drivers/input/misc/qti-haptics.c @@ -175,6 +175,7 @@ struct qti_hap_effect { u8 *pattern; int pattern_length; u16 play_rate_us; + u16 vmax_mv; u8 wf_repeat_n; u8 wf_s_repeat_n; u8 brake[HAP_BRAKE_PATTERN_MAX]; @@ -527,7 +528,6 @@ static int qti_haptics_config_brake(struct qti_hap_chip *chip, u8 *brake) { u8 addr, mask, val; int i, rc; - bool en = true; addr = REG_HAP_BRAKE; for (val = 0, i = 0; i < HAP_BRAKE_PATTERN_MAX; i++) @@ -539,14 +539,12 @@ static int qti_haptics_config_brake(struct qti_hap_chip *chip, u8 *brake) dev_err(chip->dev, "write brake pattern failed, rc=%d\n", rc); return rc; } - - if (val == 0) - en = false; - - /* Set BRAKE_EN only if brake pattern is non-zero */ + /* + * Set BRAKE_EN regardless of the brake pattern, this helps to stop + * playing immediately once the valid values in WF_Sx are played. + */ addr = REG_HAP_EN_CTL2; - mask = HAP_BRAKE_EN_BIT; - val = en; + val = mask = HAP_BRAKE_EN_BIT; rc = qti_haptics_masked_write(chip, addr, mask, val); if (rc < 0) dev_err(chip->dev, "set EN_CTL2 failed, rc=%d\n", rc); @@ -579,6 +577,9 @@ static int qti_haptics_load_constant_waveform(struct qti_hap_chip *chip) if (rc < 0) return rc; + rc = qti_haptics_config_play_rate_us(chip, config->play_rate_us); + if (rc < 0) + return rc; /* * Using VMAX waveform source if playing length is >= 20ms, * otherwise using buffer waveform source and calculate the @@ -696,7 +697,6 @@ static irqreturn_t qti_haptics_play_irq_handler(int irq, void *data) dev_dbg(chip->dev, "play_irq triggered\n"); if (play->playing_pos == effect->pattern_length) { dev_dbg(chip->dev, "waveform playing done\n"); - qti_haptics_play(chip, false); if (chip->play_irq_en) { disable_irq_nosync(chip->play_irq); chip->play_irq_en = false; @@ -830,10 +830,6 @@ static int qti_haptics_upload_effect(struct input_dev *dev, goto disable_vdd; } - level = effect->u.periodic.magnitude; - tmp = level * config->vmax_mv; - play->vmax_mv = tmp / 0x7fff; - if (copy_from_user(data, effect->u.periodic.custom_data, sizeof(s16) * CUSTOM_DATA_LEN)) { rc = -EFAULT; @@ -852,6 +848,10 @@ static int qti_haptics_upload_effect(struct input_dev *dev, goto disable_vdd; } + level = effect->u.periodic.magnitude; + tmp = level * chip->predefined[i].vmax_mv; + play->vmax_mv = tmp / 0x7fff; + dev_dbg(chip->dev, "upload effect %d, vmax_mv=%d\n", chip->predefined[i].id, play->vmax_mv); rc = qti_haptics_load_predefined_effect(chip, i); @@ -918,6 +918,10 @@ static int qti_haptics_playback(struct input_dev *dev, int effect_id, int val) enable_irq(chip->play_irq); chip->play_irq_en = true; } + /* Toggle PLAY when playing pattern */ + rc = qti_haptics_play(chip, false); + if (rc < 0) + return rc; } else { if (chip->play_irq_en) { disable_irq_nosync(chip->play_irq); @@ -966,6 +970,22 @@ static int qti_haptics_erase(struct input_dev *dev, int effect_id) return rc; } +static void qti_haptics_set_gain(struct input_dev *dev, u16 gain) +{ + struct qti_hap_chip *chip = input_get_drvdata(dev); + struct qti_hap_config *config = &chip->config; + struct qti_hap_play_info *play = &chip->play; + + if (gain == 0) + return; + + if (gain > 0x7fff) + gain = 0x7fff; + + play->vmax_mv = ((u32)(gain * config->vmax_mv)) / 0x7fff; + qti_haptics_config_vmax(chip, play->vmax_mv); +} + static int qti_haptics_hw_init(struct qti_hap_chip *chip) { struct qti_hap_config *config = &chip->config; @@ -1092,7 +1112,7 @@ static int qti_haptics_parse_dt(struct qti_hap_chip *chip) struct device_node *child_node; struct qti_hap_effect *effect; const char *str; - int rc = 0, tmp, i = 0, j; + int rc = 0, tmp, i = 0, j, m; u8 val; rc = of_property_read_u32(node, "reg", &tmp); @@ -1234,6 +1254,15 @@ static int qti_haptics_parse_dt(struct qti_hap_chip *chip) return rc; } + effect->vmax_mv = config->vmax_mv; + rc = of_property_read_u32(child_node, "qcom,wf-vmax-mv", &tmp); + if (rc < 0) + dev_dbg(chip->dev, "Read qcom,wf-vmax-mv failed, rc=%d\n", + rc); + else + effect->vmax_mv = (tmp > HAP_VMAX_MV_MAX) ? + HAP_VMAX_MV_MAX : tmp; + rc = of_property_count_elems_of_size(child_node, "qcom,wf-pattern", sizeof(u8)); if (rc < 0) { @@ -1301,7 +1330,7 @@ static int qti_haptics_parse_dt(struct qti_hap_chip *chip) effect->wf_s_repeat_n = j; } - effect->lra_auto_res_disable = of_property_read_bool(node, + effect->lra_auto_res_disable = of_property_read_bool(child_node, "qcom,lra-auto-resonance-disable"); tmp = of_property_count_elems_of_size(child_node, @@ -1337,6 +1366,28 @@ static int qti_haptics_parse_dt(struct qti_hap_chip *chip) effect->brake_en = (val != 0); } + for (j = 0; j < i; j++) { + dev_dbg(chip->dev, "effect: %d\n", chip->predefined[j].id); + dev_dbg(chip->dev, " vmax: %d mv\n", + chip->predefined[j].vmax_mv); + dev_dbg(chip->dev, " play_rate: %d us\n", + chip->predefined[j].play_rate_us); + for (m = 0; m < chip->predefined[j].pattern_length; m++) + dev_dbg(chip->dev, " pattern[%d]: 0x%x\n", + m, chip->predefined[j].pattern[m]); + for (m = 0; m < chip->predefined[j].brake_pattern_length; m++) + dev_dbg(chip->dev, " brake_pattern[%d]: 0x%x\n", + m, chip->predefined[j].brake[m]); + dev_dbg(chip->dev, " brake_en: %d\n", + chip->predefined[j].brake_en); + dev_dbg(chip->dev, " wf_repeat_n: %d\n", + chip->predefined[j].wf_repeat_n); + dev_dbg(chip->dev, " wf_s_repeat_n: %d\n", + chip->predefined[j].wf_s_repeat_n); + dev_dbg(chip->dev, " lra_auto_res_disable: %d\n", + chip->predefined[j].lra_auto_res_disable); + } + return 0; } @@ -1404,6 +1455,7 @@ static int qti_haptics_probe(struct platform_device *pdev) chip->input_dev = input_dev; input_set_capability(input_dev, EV_FF, FF_CONSTANT); + input_set_capability(input_dev, EV_FF, FF_GAIN); if (chip->effects_count != 0) { input_set_capability(input_dev, EV_FF, FF_PERIODIC); input_set_capability(input_dev, EV_FF, FF_CUSTOM); @@ -1424,6 +1476,7 @@ static int qti_haptics_probe(struct platform_device *pdev) ff->upload = qti_haptics_upload_effect; ff->playback = qti_haptics_playback; ff->erase = qti_haptics_erase; + ff->set_gain = qti_haptics_set_gain; rc = input_register_device(input_dev); if (rc < 0) { diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c index cddbd8309ece..f2796be6d682 100644 --- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c +++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c @@ -422,7 +422,7 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw, } for (i = 0; i < req->data->cmd_arrary_count ; i++) { - uint64_t hw_vaddr_ptr = 0; + dma_addr_t hw_vaddr_ptr = 0; size_t len = 0; if ((!cdm_cmd->cmd[i].len) && @@ -470,7 +470,7 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw, } rc = 0; hw_vaddr_ptr = - (uint64_t)cdm_cmd->cmd[i].bl_addr.hw_iova; + (dma_addr_t) cdm_cmd->cmd[i].bl_addr.hw_iova; len = cdm_cmd->cmd[i].len + cdm_cmd->cmd[i].offset; } else { CAM_ERR(CAM_CDM, diff --git a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c index 212065050d81..053447e331a8 100644 --- a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c +++ b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c @@ -581,15 +581,16 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate( required_camnoc_bw); } - required_camnoc_bw += (required_camnoc_bw * - soc_private->camnoc_axi_clk_bw_margin) / 100; + required_camnoc_bw += div64_u64((required_camnoc_bw * + soc_private->camnoc_axi_clk_bw_margin), 100); if ((required_camnoc_bw > 0) && (required_camnoc_bw < soc_private->camnoc_axi_min_ib_bw)) required_camnoc_bw = soc_private->camnoc_axi_min_ib_bw; - clk_rate = required_camnoc_bw / soc_private->camnoc_bus_width; + clk_rate = div64_u64(required_camnoc_bw, + soc_private->camnoc_bus_width); CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %d", required_camnoc_bw, clk_rate); diff --git a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c index d3c39f940f05..09388fe40c70 100644 --- a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c @@ -536,7 +536,7 @@ static int cam_fd_mgr_util_prepare_io_buf_info(int32_t iommu_hdl, int rc = -EINVAL; uint32_t i, j, plane, num_out_buf, num_in_buf; struct cam_buf_io_cfg *io_cfg; - uint64_t io_addr[CAM_PACKET_MAX_PLANES]; + dma_addr_t io_addr[CAM_PACKET_MAX_PLANES]; uint64_t cpu_addr[CAM_PACKET_MAX_PLANES]; size_t size; bool need_io_map, need_cpu_map; diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 1733017a3106..4aa2b61104b8 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -599,7 +599,7 @@ static uint32_t cam_icp_mgr_calc_base_clk(uint32_t frame_cycles, uint64_t base_clk; uint64_t mul = 1000000000; - base_clk = (frame_cycles * mul) / budget; + base_clk = div64_u64((frame_cycles * mul), budget); CAM_DBG(CAM_ICP, "budget = %lld fc = %d ib = %lld base_clk = %lld", budget, frame_cycles, @@ -3099,7 +3099,7 @@ static int cam_icp_mgr_send_config_io(struct cam_icp_hw_ctx_data *ctx_data, task_data->type = ICP_WORKQ_TASK_MSG_TYPE; task->process_cb = cam_icp_mgr_process_cmd; size_in_words = (*(uint32_t *)task_data->data) >> 2; - CAM_INFO(CAM_ICP, "size_in_words %u", size_in_words); + CAM_DBG(CAM_ICP, "size_in_words %u", size_in_words); rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr, CRM_TASK_PRIORITY_0); if (rc) @@ -3175,8 +3175,8 @@ static int cam_icp_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) frame_info = (struct icp_frame_info *)config_args->priv; req_id = frame_info->request_id; idx = cam_icp_clk_idx_from_req_id(ctx_data, req_id); - ctx_data->hfi_frame_process.fw_process_flag[idx] = true; cam_icp_mgr_ipe_bps_clk_update(hw_mgr, ctx_data, idx); + ctx_data->hfi_frame_process.fw_process_flag[idx] = true; CAM_DBG(CAM_ICP, "req_id %llu, io config %llu", req_id, frame_info->io_config); @@ -3268,7 +3268,7 @@ static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr, { int rc = 0; int i, j, k; - uint64_t addr; + dma_addr_t addr; size_t len; struct cam_cmd_buf_desc *cmd_desc = NULL; uint64_t cpu_addr = 0; @@ -3490,7 +3490,7 @@ static int cam_icp_process_generic_cmd_buffer( struct cam_packet *packet, struct cam_icp_hw_ctx_data *ctx_data, int32_t index, - uint64_t *io_buf_addr) + dma_addr_t *io_buf_addr) { int i, rc = 0; struct cam_cmd_buf_desc *cmd_desc = NULL; @@ -4132,7 +4132,7 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) { int rc = 0, bitmap_size = 0; uint32_t ctx_id = 0; - uint64_t io_buf_addr; + dma_addr_t io_buf_addr; size_t io_buf_size; struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv; struct cam_icp_hw_ctx_data *ctx_data = NULL; diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h index 0b931f3c7636..8c132c52739d 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h @@ -135,7 +135,7 @@ struct clk_work_data { */ struct icp_frame_info { uint64_t request_id; - uint64_t io_config; + dma_addr_t io_config; struct hfi_cmd_ipebps_async hfi_cfg_io_cmd; }; @@ -238,7 +238,7 @@ struct cam_icp_hw_ctx_data { struct icp_cmd_generic_blob { struct cam_icp_hw_ctx_data *ctx; uint32_t frame_info_idx; - uint64_t *io_buf_addr; + dma_addr_t *io_buf_addr; }; /** diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index 08ef0e9dcf19..bd1e6b1dffbd 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -25,19 +25,15 @@ #include "cam_debug_util.h" static const char isp_dev_name[] = "isp"; - -#define INC_STATE_MONITOR_HEAD(head) \ - (atomic64_add_return(1, head) % \ - CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) - static void __cam_isp_ctx_update_state_monitor_array( struct cam_isp_context *ctx_isp, enum cam_isp_state_change_trigger trigger_type, uint32_t req_id) { - int iterator = 0; + uint64_t iterator = 0; - iterator = INC_STATE_MONITOR_HEAD(&ctx_isp->state_monitor_head); + div64_u64_rem(atomic64_add_return(1, &ctx_isp->state_monitor_head), + CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES, &iterator); ctx_isp->cam_isp_ctx_state_monitor[iterator].curr_state = ctx_isp->substate_activated; ctx_isp->cam_isp_ctx_state_monitor[iterator].trigger = @@ -96,6 +92,7 @@ static void __cam_isp_ctx_dump_state_monitor_array( int i = 0; uint64_t state_head = 0; uint64_t index; + struct cam_isp_context_state_monitor *cam_isp_ctx_state_monitor; state_head = atomic64_read(&ctx_isp->state_monitor_head); CAM_ERR_RATE_LIMIT(CAM_ISP, @@ -103,17 +100,20 @@ static void __cam_isp_ctx_dump_state_monitor_array( for (i = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES - 1; i >= 0; i--) { - index = (((state_head - i) + - CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) % - CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES); + div64_u64_rem(((state_head - i) + + CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES), + CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES, &index); + cam_isp_ctx_state_monitor = + &ctx_isp->cam_isp_ctx_state_monitor[index]; + CAM_ERR_RATE_LIMIT(CAM_ISP, - "time[0x%llx] req_id[%u] state[%s] evt_type[%s]", - ctx_isp->cam_isp_ctx_state_monitor[index].evt_time_stamp, - ctx_isp->cam_isp_ctx_state_monitor[index].req_id, - __cam_isp_ctx_substate_val_to_type( - ctx_isp->cam_isp_ctx_state_monitor[index].curr_state), - __cam_isp_hw_evt_val_to_type( - ctx_isp->cam_isp_ctx_state_monitor[index].trigger)); + "time[0x%llx] req_id[%u] state[%s] evt_type[%s]", + cam_isp_ctx_state_monitor->evt_time_stamp, + cam_isp_ctx_state_monitor->req_id, + __cam_isp_ctx_substate_val_to_type( + cam_isp_ctx_state_monitor->curr_state), + __cam_isp_hw_evt_val_to_type( + cam_isp_ctx_state_monitor->trigger)); } } @@ -524,11 +524,11 @@ static int __cam_isp_ctx_reg_upd_in_activated_state( struct cam_context *ctx = ctx_isp->base; struct cam_isp_ctx_req *req_isp; - if (list_empty(&ctx->pending_req_list)) { - CAM_ERR(CAM_ISP, "Reg upd ack with no pending request"); + if (list_empty(&ctx->wait_req_list)) { + CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request"); goto end; } - req = list_first_entry(&ctx->pending_req_list, + req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request, list); list_del_init(&req->list); @@ -686,24 +686,16 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, * This is for the first update. The initial setting will * cause the reg_upd in the first frame. */ - if (!list_empty(&ctx->pending_req_list)) { - req = list_first_entry(&ctx->pending_req_list, + if (!list_empty(&ctx->wait_req_list)) { + req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request, list); list_del_init(&req->list); req_isp = (struct cam_isp_ctx_req *) req->req_priv; - if (req_isp->num_fence_map_out == req_isp->num_acked) { + if (req_isp->num_fence_map_out == req_isp->num_acked) list_add_tail(&req->list, &ctx->free_req_list); - } else { - /* need to handle the buf done */ - list_add_tail(&req->list, &ctx->active_req_list); - ctx_isp->active_req_cnt++; - CAM_DBG(CAM_REQ, - "move request %lld to active list(cnt = %d)", - req->request_id, - ctx_isp->active_req_cnt); - ctx_isp->substate_activated = - CAM_ISP_CTX_ACTIVATED_EPOCH; - } + else + CAM_ERR(CAM_ISP, + "receive rup in unexpected state"); } if (req != NULL) { __cam_isp_ctx_update_state_monitor_array(ctx_isp, @@ -722,12 +714,12 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, struct cam_context *ctx = ctx_isp->base; uint64_t request_id = 0; - if (list_empty(&ctx->pending_req_list)) { + if (list_empty(&ctx->wait_req_list)) { /* - * If no pending req in epoch, this is an error case. + * If no wait req in epoch, this is an error case. * The recovery is to go back to sof state */ - CAM_ERR(CAM_ISP, "No pending request"); + CAM_ERR(CAM_ISP, "No wait request"); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; /* Send SOF event as empty frame*/ @@ -737,7 +729,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, goto end; } - req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request, + req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request, list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; @@ -746,6 +738,9 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; + list_del_init(&req->list); + list_add(&req->list, &ctx->pending_req_list); + notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.req_id = req->request_id; @@ -826,8 +821,10 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp, req = list_last_entry(&ctx->active_req_list, struct cam_ctx_request, list); - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, ctx->req_list->request_id); + if (req) + __cam_isp_ctx_update_state_monitor_array(ctx_isp, + CAM_ISP_STATE_CHANGE_TRIGGER_SOF, + ctx->req_list->request_id); CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); @@ -869,7 +866,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( * transition to BUBBLE state again. */ - if (list_empty(&ctx->pending_req_list)) { + if (list_empty(&ctx->wait_req_list)) { /* * If no pending req in epoch, this is an error case. * Just go back to the bubble state. @@ -882,14 +879,16 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( goto end; } - req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request, + req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request, list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; + list_del_init(&req->list); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; + list_add(&req->list, &ctx->pending_req_list); notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.req_id = req->request_id; @@ -903,7 +902,6 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( * If we can not report bubble, then treat it as if no bubble * report. Just move the req to active list. */ - list_del_init(&req->list); list_add_tail(&req->list, &ctx->active_req_list); ctx_isp->active_req_cnt++; CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)", @@ -929,8 +927,9 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( end: req = list_last_entry(&ctx->active_req_list, struct cam_ctx_request, list); - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); + if (req) + __cam_isp_ctx_update_state_monitor_array(ctx_isp, + CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); return 0; } @@ -1079,30 +1078,6 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, return rc; } -static int __cam_isp_ctx_sof_in_flush( - struct cam_isp_context *ctx_isp, void *evt_data) -{ - int rc = 0; - struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; - - if (!evt_data) { - CAM_ERR(CAM_ISP, "in valid sof event data"); - return -EINVAL; - } - ctx_isp->frame_id++; - ctx_isp->sof_timestamp_val = sof_event_data->timestamp; - ctx_isp->boot_timestamp = sof_event_data->boot_time; - CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx", - ctx_isp->frame_id, ctx_isp->sof_timestamp_val); - - if (--ctx_isp->frame_skip_count == 0) - ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; - else - CAM_ERR(CAM_ISP, "Skip currect SOF"); - - return rc; -} - static struct cam_isp_ctx_irq_ops cam_isp_ctx_activated_state_machine_irq[CAM_ISP_CTX_ACTIVATED_MAX] = { /* SOF */ @@ -1174,17 +1149,6 @@ static struct cam_isp_ctx_irq_ops /* HALT */ { }, - /* FLUSH */ - { - .irq_ops = { - NULL, - __cam_isp_ctx_sof_in_flush, - NULL, - NULL, - NULL, - __cam_isp_ctx_buf_done_in_applied, - }, - }, }; static int __cam_isp_ctx_apply_req_in_activated_state( @@ -1267,6 +1231,8 @@ static int __cam_isp_ctx_apply_req_in_activated_state( spin_lock_bh(&ctx->lock); ctx_isp->substate_activated = next_state; ctx_isp->last_applied_req_id = apply->request_id; + list_del_init(&req->list); + list_add_tail(&req->list, &ctx->wait_req_list); CAM_DBG(CAM_ISP, "new substate state %d, applied req %lld", next_state, ctx_isp->last_applied_req_id); spin_unlock_bh(&ctx->lock); @@ -1341,7 +1307,11 @@ static int __cam_isp_ctx_flush_req(struct cam_context *ctx, INIT_LIST_HEAD(&flush_list); if (list_empty(req_list)) { CAM_DBG(CAM_ISP, "request list is empty"); - return 0; + if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ) { + CAM_ERR(CAM_ISP, "no request to cancel"); + return -EINVAL; + } else + return 0; } CAM_DBG(CAM_REQ, "Flush [%u] in progress for req_id %llu", @@ -1450,28 +1420,6 @@ end: return rc; } -static int __cam_isp_ctx_flush_req_in_activated( - struct cam_context *ctx, - struct cam_req_mgr_flush_request *flush_req) -{ - int rc = 0; - struct cam_isp_context *ctx_isp; - - ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; - - CAM_DBG(CAM_ISP, "Flush request in state %d", ctx->state); - rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req); - - /* only if request is found in pending queue, move to flush state*/ - if (!rc) { - spin_lock_bh(&ctx->lock); - ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_FLUSH; - ctx_isp->frame_skip_count = 2; - spin_unlock_bh(&ctx->lock); - } - return rc; -} - static int __cam_isp_ctx_flush_req_in_ready( struct cam_context *ctx, struct cam_req_mgr_flush_request *flush_req) @@ -1544,12 +1492,6 @@ static struct cam_ctx_ops .crm_ops = {}, .irq_ops = NULL, }, - /* FLUSH */ - { - .ioctl_ops = {}, - .crm_ops = {}, - .irq_ops = NULL, - }, }; static int __cam_isp_ctx_rdi_only_sof_in_top_state( @@ -1807,11 +1749,11 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH; /* notify reqmgr with sof signal*/ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) { - if (list_empty(&ctx->pending_req_list)) { - CAM_ERR(CAM_ISP, "Reg upd ack with no pending request"); + if (list_empty(&ctx->wait_req_list)) { + CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request"); goto error; } - req = list_first_entry(&ctx->pending_req_list, + req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request, list); list_del_init(&req->list); @@ -1934,17 +1876,6 @@ static struct cam_isp_ctx_irq_ops /* HALT */ { }, - /* FLUSH */ - { - .irq_ops = { - NULL, - __cam_isp_ctx_sof_in_flush, - NULL, - NULL, - NULL, - __cam_isp_ctx_buf_done_in_applied, - }, - }, }; static int __cam_isp_ctx_rdi_only_apply_req_top_state( @@ -2012,12 +1943,6 @@ static struct cam_ctx_ops .crm_ops = {}, .irq_ops = NULL, }, - /* FLUSHED */ - { - .ioctl_ops = {}, - .crm_ops = {}, - .irq_ops = NULL, - }, }; /* top level state machine */ @@ -2473,9 +2398,13 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, } CAM_DBG(CAM_ISP, "start device success ctx %u", ctx->ctx_id); + list_del_init(&req->list); + if (req_isp->num_fence_map_out) { - list_del_init(&req->list); list_add_tail(&req->list, &ctx->active_req_list); + ctx_isp->active_req_cnt++; + } else { + list_add_tail(&req->list, &ctx->wait_req_list); } end: return rc; @@ -2817,7 +2746,7 @@ static struct cam_ctx_ops .crm_ops = { .unlink = __cam_isp_ctx_unlink_in_activated, .apply_req = __cam_isp_ctx_apply_req, - .flush_req = __cam_isp_ctx_flush_req_in_activated, + .flush_req = __cam_isp_ctx_flush_req_in_top_state, .process_evt = __cam_isp_ctx_process_evt, }, .irq_ops = __cam_isp_ctx_handle_irq_in_activated, diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h index a939f2d80b34..4592e42932d8 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h @@ -57,7 +57,6 @@ enum cam_isp_ctx_activated_substate { CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED, CAM_ISP_CTX_ACTIVATED_HW_ERROR, CAM_ISP_CTX_ACTIVATED_HALT, - CAM_ISP_CTX_ACTIVATED_FLUSH, CAM_ISP_CTX_ACTIVATED_MAX, }; @@ -155,7 +154,6 @@ struct cam_isp_context_state_monitor { * @subscribe_event: The irq event mask that CRM subscribes to, IFE * will invoke CRM cb at those event. * @last_applied_req_id: Last applied request id - * @frame_skip_count: Number of frame to skip before change state * @state_monitor_head: Write index to the state monitoring array * @cam_isp_ctx_state_monitor: State monitoring array * @rdi_only_context: Get context type information. @@ -180,7 +178,6 @@ struct cam_isp_context { int64_t reported_req_id; uint32_t subscribe_event; int64_t last_applied_req_id; - uint32_t frame_skip_count; atomic64_t state_monitor_head; struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES]; diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index abc6bb0a6db8..eaa7325fbca8 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -434,7 +434,7 @@ int cam_isp_add_io_buffers( bool fill_fence) { int rc = 0; - uint64_t io_addr[CAM_PACKET_MAX_PLANES]; + dma_addr_t io_addr[CAM_PACKET_MAX_PLANES]; struct cam_buf_io_cfg *io_cfg; struct cam_isp_resource_node *res; struct cam_ife_hw_mgr_res *hw_mgr_res; diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index 70e04677282d..28cfcc8bea74 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -177,7 +177,7 @@ struct cam_isp_hw_cmd_buf_update { * */ struct cam_isp_hw_get_wm_update { - uint64_t *image_buf; + dma_addr_t *image_buf; uint32_t num_buf; struct cam_buf_io_cfg *io_cfg; }; diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c index 0f34c9f15b56..fa8984ca2300 100644 --- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c @@ -150,7 +150,7 @@ static int cam_lrme_mgr_util_prepare_io_buffer(int32_t iommu_hdl, int rc = -EINVAL; uint32_t num_in_buf, num_out_buf, i, j, plane; struct cam_buf_io_cfg *io_cfg; - uint64_t io_addr[CAM_PACKET_MAX_PLANES]; + dma_addr_t io_addr[CAM_PACKET_MAX_PLANES]; size_t size; num_in_buf = 0; diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c index d192018bf2f2..0e77a4c01fb4 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c @@ -147,7 +147,7 @@ static void cam_mem_put_slot(int32_t idx) } int cam_mem_get_io_buf(int32_t buf_handle, int32_t mmu_handle, - uint64_t *iova_ptr, size_t *len_ptr) + dma_addr_t *iova_ptr, size_t *len_ptr) { int rc = 0, idx; diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h index 7588c179f4a5..14b1a678e010 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -82,7 +82,7 @@ int cam_mem_mgr_release_mem(struct cam_mem_mgr_memory_desc *inp); * @return Status of operation. Negative in case of error. Zero otherwise. */ int cam_mem_get_io_buf(int32_t buf_handle, int32_t mmu_handle, - uint64_t *iova_ptr, size_t *len_ptr); + dma_addr_t *iova_ptr, size_t *len_ptr); /** * @brief: Returns CPU address information about buffer * diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index 61fd7a85290d..460b3dfe59a2 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -1283,7 +1283,8 @@ static int __cam_req_mgr_destroy_link_info(struct cam_req_mgr_core_link *link) rc = dev->ops->link_setup(&link_data); if (rc) CAM_ERR(CAM_CRM, - "Unlink failed dev_hdl %d", + "Unlink failed dev name %s hdl %x", + dev->dev_info.name, dev->dev_hdl); } dev->dev_hdl = 0; @@ -2350,8 +2351,8 @@ static int __cam_req_mgr_unlink(struct cam_req_mgr_core_link *link) /* Destroy the link handle */ rc = cam_destroy_device_hdl(link->link_hdl); if (rc < 0) { - CAM_ERR(CAM_CRM, "error while destroying dev handle %d %x", - rc, link->link_hdl); + CAM_ERR(CAM_CRM, "error destroying link hdl %x rc %d", + link->link_hdl, rc); } mutex_unlock(&link->lock); @@ -2552,8 +2553,7 @@ int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info) rc = __cam_req_mgr_unlink(link); /* Free curent link and put back into session's free pool of links */ - if (!rc) - __cam_req_mgr_unreserve_link(cam_session, link); + __cam_req_mgr_unreserve_link(cam_session, link); done: mutex_unlock(&g_crm_core_dev->crm_lock); diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c index 058e3528e248..f859484b178f 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c @@ -870,8 +870,8 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, struct cam_cci_ctrl *c_ctrl) { int32_t rc = 0; - uint32_t val = 0, i = 0; - unsigned long rem_jiffies; + uint32_t val = 0, i = 0, j = 0; + unsigned long rem_jiffies, flags; int32_t read_words = 0, exp_words = 0; int32_t index = 0, first_byte = 0, total_read_words = 0; enum cci_i2c_master_t master; @@ -990,11 +990,13 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, val = 1 << ((master * 2) + queue); cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR); + exp_words = ((read_cfg->num_byte / 4) + 1); + CAM_DBG(CAM_CCI, "waiting for threshold [exp_words %d]", exp_words); - while (exp_words != total_read_words) { + while (total_read_words != exp_words) { rem_jiffies = wait_for_completion_timeout( - &cci_dev->cci_master_info[master].reset_complete, + &cci_dev->cci_master_info[master].th_complete, CCI_TIMEOUT); if (!rem_jiffies) { rc = -ETIMEDOUT; @@ -1013,8 +1015,16 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, read_words = cam_io_r_mb(base + CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100); + if (read_words <= 0) { + CAM_DBG(CAM_CCI, "FIFO Buffer lvl is 0"); + continue; + } + + j++; + CAM_DBG(CAM_CCI, "Iteration: %u read_words %d", j, read_words); + total_read_words += read_words; - do { + while (read_words > 0) { val = cam_io_r_mb(base + CCI_I2C_M0_READ_DATA_ADDR + master * 0x100); for (i = 0; (i < 4) && @@ -1032,9 +1042,57 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, index++; } } - } while (--read_words > 0); + read_words--; + } + + CAM_DBG(CAM_CCI, "Iteraion:%u total_read_words %d", + j, total_read_words); + + spin_lock_irqsave(&cci_dev->lock_status, flags); + if (cci_dev->irq_status1) { + CAM_DBG(CAM_CCI, "clear irq_status1:%x", + cci_dev->irq_status1); + cam_io_w_mb(cci_dev->irq_status1, + base + CCI_IRQ_CLEAR_1_ADDR); + cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR); + cci_dev->irq_status1 = 0; + } + spin_unlock_irqrestore(&cci_dev->lock_status, flags); + + if (total_read_words == exp_words) { + /* + * This wait is for RD_DONE irq, if RD_DONE is + * triggered we will call complete on both threshold + * & read done waits. As part of the threshold wait + * we will be draining the entire buffer out. This + * wait is to compensate for the complete invoked for + * RD_DONE exclusively. + */ + rem_jiffies = wait_for_completion_timeout( + &cci_dev->cci_master_info[master].reset_complete, + CCI_TIMEOUT); + if (!rem_jiffies) { + rc = -ETIMEDOUT; + val = cam_io_r_mb(base + + CCI_I2C_M0_READ_BUF_LEVEL_ADDR + + master * 0x100); + CAM_ERR(CAM_CCI, + "Failed to receive RD_DONE irq rc = %d FIFO buf_lvl:0x%x", + rc, val); + #ifdef DUMP_CCI_REGISTERS + cam_cci_dump_registers(cci_dev, + master, queue); + #endif + cam_cci_flush_queue(cci_dev, master); + goto rel_mutex; + } + break; + } } + CAM_DBG(CAM_CCI, "Burst read successful words_read %d", + total_read_words); + rel_mutex: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); return rc; @@ -1166,7 +1224,8 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, val = 1 << ((master * 2) + queue); cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR); - CAM_DBG(CAM_CCI, "wait_for_completion_timeout"); + CAM_DBG(CAM_CCI, + "waiting_for_rd_done [exp_words: %d]", exp_words); rc = wait_for_completion_timeout( &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); @@ -1200,7 +1259,7 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, index = 0; CAM_DBG(CAM_CCI, "index %d num_type %d", index, read_cfg->num_byte); first_byte = 0; - do { + while (read_words > 0) { val = cam_io_r_mb(base + CCI_I2C_M0_READ_DATA_ADDR + master * 0x100); CAM_DBG(CAM_CCI, "read val 0x%x", val); @@ -1217,10 +1276,10 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, index++; } } - } while (--read_words > 0); + read_words--; + } rel_mutex: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); - return rc; } @@ -1399,23 +1458,34 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd, } read_bytes = read_cfg->num_byte; + + /* + * To avoid any conflicts due to back to back trigger of + * THRESHOLD irq's, we reinit the threshold wait before + * we load the burst read cmd. + */ + reinit_completion(&cci_dev->cci_master_info[master].th_complete); + + CAM_DBG(CAM_CCI, "Bytes to read %u", read_bytes); do { - if (read_bytes > CCI_I2C_MAX_BYTE_COUNT) + if (read_bytes >= CCI_I2C_MAX_BYTE_COUNT) read_cfg->num_byte = CCI_I2C_MAX_BYTE_COUNT; else read_cfg->num_byte = read_bytes; - if (read_cfg->num_byte > CCI_READ_MAX) + if (read_cfg->num_byte >= CCI_READ_MAX) { + cci_dev->is_burst_read = true; rc = cam_cci_burst_read(sd, c_ctrl); - else + } else { + cci_dev->is_burst_read = false; rc = cam_cci_read(sd, c_ctrl); - + } if (rc) { CAM_ERR(CAM_CCI, "failed to read rc:%d", rc); goto ERROR; } - if (read_bytes > CCI_I2C_MAX_BYTE_COUNT) { + if (read_bytes >= CCI_I2C_MAX_BYTE_COUNT) { read_cfg->addr += (CCI_I2C_MAX_BYTE_COUNT / read_cfg->data_type); read_cfg->data += CCI_I2C_MAX_BYTE_COUNT; @@ -1426,6 +1496,7 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd, } while (read_bytes); ERROR: + cci_dev->is_burst_read = false; return rc; } diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c index ce7ac3f0b820..958737f1a879 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c @@ -65,15 +65,12 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; unsigned long flags; - bool burst_read_assert = false; + bool rd_done_th_assert = false; irq_status0 = cam_io_r_mb(base + CCI_IRQ_STATUS_0_ADDR); irq_status1 = cam_io_r_mb(base + CCI_IRQ_STATUS_1_ADDR); - cam_io_w_mb(irq_status0, base + CCI_IRQ_CLEAR_0_ADDR); - cam_io_w_mb(irq_status1, base + CCI_IRQ_CLEAR_1_ADDR); - cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR); - CAM_DBG(CAM_CCI, "irq0:%x irq1:%x", irq_status0, irq_status1); + if (irq_status0 & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) { if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) { cci_dev->cci_master_info[MASTER_0].reset_pending = @@ -92,18 +89,23 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) && (irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD)) { cci_dev->cci_master_info[MASTER_0].status = 0; + rd_done_th_assert = true; + complete(&cci_dev->cci_master_info[MASTER_0].th_complete); complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); - burst_read_assert = true; } if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) && - (!burst_read_assert)) { + (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_0].status = 0; + rd_done_th_assert = true; + if (cci_dev->is_burst_read) + complete( + &cci_dev->cci_master_info[MASTER_0].th_complete); complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD) && - (!burst_read_assert)) { + (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_0].status = 0; - complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); + complete(&cci_dev->cci_master_info[MASTER_0].th_complete); } if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; @@ -142,18 +144,23 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) && (irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD)) { cci_dev->cci_master_info[MASTER_1].status = 0; + rd_done_th_assert = true; + complete(&cci_dev->cci_master_info[MASTER_1].th_complete); complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); - burst_read_assert = true; } if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) && - (!burst_read_assert)) { + (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_1].status = 0; + rd_done_th_assert = true; + if (cci_dev->is_burst_read) + complete( + &cci_dev->cci_master_info[MASTER_1].th_complete); complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD) && - (!burst_read_assert)) { + (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_1].status = 0; - complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); + complete(&cci_dev->cci_master_info[MASTER_1].th_complete); } if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; @@ -189,6 +196,12 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_1].lock_q[QUEUE_1], flags); } + if (irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_PAUSE) + CAM_DBG(CAM_CCI, "RD_PAUSE ON MASTER_0"); + + if (irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_PAUSE) + CAM_DBG(CAM_CCI, "RD_PAUSE ON MASTER_1"); + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) { cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; cam_io_w_mb(CCI_M0_RESET_RMSK, @@ -211,6 +224,19 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) base + CCI_HALT_REQ_ADDR); CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq_status0); } + + if ((rd_done_th_assert) || (!cci_dev->is_burst_read)) { + cam_io_w_mb(irq_status1, base + CCI_IRQ_CLEAR_1_ADDR); + CAM_DBG(CAM_CCI, "clear irq_status0:%x irq_status1:%x", + irq_status0, irq_status1); + } else { + spin_lock_irqsave(&cci_dev->lock_status, flags); + cci_dev->irq_status1 |= irq_status1; + spin_unlock_irqrestore(&cci_dev->lock_status, flags); + } + + cam_io_w_mb(irq_status0, base + CCI_IRQ_CLEAR_0_ADDR); + cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR); return IRQ_HANDLED; } diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h index d48ffd15b4f9..aec86baf89aa 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h @@ -137,6 +137,7 @@ struct cam_cci_master_info { uint8_t reset_pending; struct mutex mutex; struct completion reset_complete; + struct completion th_complete; struct mutex mutex_q[NUM_QUEUES]; struct completion report_q[NUM_QUEUES]; atomic_t done_pending[NUM_QUEUES]; @@ -192,6 +193,11 @@ enum cam_cci_state_t { * @cci_wait_sync_cfg: CCI sync config * @cycles_per_us: Cycles per micro sec * @payload_size: CCI packet payload size + * @irq_status1: Store irq_status1 to be cleared after + * draining FIFO buffer for burst read + * @lock_status: to protect changes to irq_status1 + * @is_burst_read: Flag to determine if we are performing + * a burst read operation or not */ struct cci_device { struct v4l2_subdev subdev; @@ -216,6 +222,9 @@ struct cci_device { uint8_t payload_size; char device_name[20]; uint32_t cpas_handle; + uint32_t irq_status1; + spinlock_t lock_status; + bool is_burst_read; }; enum cam_cci_i2c_cmd_type { diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h index 31c8e26f3f90..65a48e11fbd7 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h @@ -56,15 +56,17 @@ #define CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK 0x10000 #define CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK 0x1000 #define CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD 0x100000 +#define CCI_IRQ_STATUS_1_I2C_M1_RD_PAUSE 0x200000 #define CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK 0x100 #define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK 0x10 #define CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK 0x18000EE6 #define CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK 0x60EE6000 #define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK 0x1 #define CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD 0x10000 +#define CCI_IRQ_STATUS_1_I2C_M0_RD_PAUSE 0x20000 #define CCI_I2C_M0_RD_THRESHOLD_ADDR 0x00000120 #define CCI_I2C_M1_RD_THRESHOLD_ADDR 0x00000220 -#define CCI_I2C_RD_THRESHOLD_VALUE 0x38 +#define CCI_I2C_RD_THRESHOLD_VALUE 0x30 #define CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR 0x00000c00 #define DEBUG_TOP_REG_START 0x0 diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c index e0b27ca1e92a..8c2853b5cc62 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c @@ -199,6 +199,8 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) mutex_init(&new_cci_dev->cci_master_info[i].mutex); init_completion( &new_cci_dev->cci_master_info[i].reset_complete); + init_completion( + &new_cci_dev->cci_master_info[i].th_complete); for (j = 0; j < NUM_QUEUES; j++) { mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); @@ -208,6 +210,7 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) &new_cci_dev->cci_master_info[i].lock_q[j]); } } + spin_lock_init(&new_cci_dev->lock_status); } static void cam_cci_init_default_clk_params(struct cci_device *cci_dev, diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index bc61df42bb94..2e9aa6cbb1db 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -296,12 +296,14 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev) continue; } - settle_cnt = (csiphy_dev->csiphy_info.settle_time / 200000000); + settle_cnt = div64_u64(csiphy_dev->csiphy_info.settle_time, + 200000000); if (csiphy_dev->csiphy_info.combo_mode == 1 && (lane_pos >= 3)) settle_cnt = - (csiphy_dev->csiphy_info.settle_time_combo_sensor / - 200000000); + div64_u64(csiphy_dev->csiphy_info. + settle_time_combo_sensor, + 200000000); for (i = 0; i < cfg_size; i++) { switch (reg_array[lane_pos][i].csiphy_param_type) { case CSIPHY_LANE_ENABLE: diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync.c b/drivers/media/platform/msm/camera/cam_sync/cam_sync.c index e5df874b52ae..c5438c917bc0 100644 --- a/drivers/media/platform/msm/camera/cam_sync/cam_sync.c +++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync.c @@ -21,6 +21,13 @@ struct sync_device *sync_dev; +/* + * Flag to determine whether to enqueue cb of a + * signaled fence onto the workq or invoke it + * directly in the same context + */ +static bool trigger_cb_without_switch; + int cam_sync_create(int32_t *sync_obj, const char *name) { int rc; @@ -59,6 +66,7 @@ int cam_sync_register_callback(sync_callback cb_func, struct sync_callback_info *sync_cb; struct sync_callback_info *cb_info; struct sync_table_row *row = NULL; + int status = 0; if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0 || !cb_func) return -EINVAL; @@ -95,18 +103,27 @@ int cam_sync_register_callback(sync_callback cb_func, if ((row->state == CAM_SYNC_STATE_SIGNALED_SUCCESS || row->state == CAM_SYNC_STATE_SIGNALED_ERROR) && (!row->remaining)) { - sync_cb->callback_func = cb_func; - sync_cb->cb_data = userdata; - sync_cb->sync_obj = sync_obj; - INIT_WORK(&sync_cb->cb_dispatch_work, - cam_sync_util_cb_dispatch); - sync_cb->status = row->state; - CAM_DBG(CAM_SYNC, "Callback trigger for sync object:%d", - sync_cb->sync_obj); - queue_work(sync_dev->work_queue, - &sync_cb->cb_dispatch_work); + if (trigger_cb_without_switch) { + CAM_DBG(CAM_SYNC, "Invoke callback for sync object:%d", + sync_obj); + status = row->state; + kfree(sync_cb); + spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]); + cb_func(sync_obj, status, userdata); + } else { + sync_cb->callback_func = cb_func; + sync_cb->cb_data = userdata; + sync_cb->sync_obj = sync_obj; + INIT_WORK(&sync_cb->cb_dispatch_work, + cam_sync_util_cb_dispatch); + sync_cb->status = row->state; + CAM_DBG(CAM_SYNC, "Enqueue callback for sync object:%d", + sync_cb->sync_obj); + queue_work(sync_dev->work_queue, + &sync_cb->cb_dispatch_work); + spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]); + } - spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]); return 0; } @@ -158,19 +175,11 @@ int cam_sync_deregister_callback(sync_callback cb_func, int cam_sync_signal(int32_t sync_obj, uint32_t status) { - int rc; struct sync_table_row *row = NULL; struct sync_table_row *parent_row = NULL; - struct sync_callback_info *sync_cb; - struct sync_user_payload *payload_info; - struct sync_parent_info *parent_info; - struct list_head sync_list; - struct cam_signalable_info *list_info = NULL; - struct cam_signalable_info *temp_list_info = NULL; + struct sync_parent_info *parent_info, *temp_parent_info; struct list_head parents_list; - - /* Objects to be signaled will be added into this list */ - INIT_LIST_HEAD(&sync_list); + int rc = 0; if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0) { CAM_ERR(CAM_SYNC, "Error: Out of range sync obj (0 <= %d < %d)", @@ -213,14 +222,7 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status) } row->state = status; - rc = cam_sync_util_add_to_signalable_list(sync_obj, status, &sync_list); - if (rc < 0) { - spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]); - CAM_ERR(CAM_SYNC, - "Error: Unable to add sync object :%d to signalable list", - sync_obj); - return rc; - } + cam_sync_util_dispatch_signaled_cb(sync_obj, status); /* copy parent list to local and release child lock */ INIT_LIST_HEAD(&parents_list); @@ -228,13 +230,14 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status) spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]); if (list_empty(&parents_list)) - goto dispatch_cb; + return 0; /* * Now iterate over all parents of this object and if they too need to - * be signaled add them to the list + * be signaled dispatch cb's */ - list_for_each_entry(parent_info, + list_for_each_entry_safe(parent_info, + temp_parent_info, &parents_list, list) { parent_row = sync_dev->sync_table + parent_info->sync_id; @@ -253,93 +256,16 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status) continue; } - if (!parent_row->remaining) { - rc = cam_sync_util_add_to_signalable_list - (parent_info->sync_id, - parent_row->state, - &sync_list); - if (rc < 0) { - spin_unlock_bh( - &sync_dev->row_spinlocks[ - parent_info->sync_id]); - continue; - } - } - spin_unlock_bh(&sync_dev->row_spinlocks[parent_info->sync_id]); - } - -dispatch_cb: - - /* - * Now dispatch the various sync objects collected so far, in our - * list - */ - list_for_each_entry_safe(list_info, - temp_list_info, - &sync_list, - list) { - struct sync_table_row *signalable_row = NULL; - struct sync_callback_info *temp_sync_cb; - struct sync_user_payload *temp_payload_info; - - signalable_row = sync_dev->sync_table + list_info->sync_obj; - - spin_lock_bh(&sync_dev->row_spinlocks[list_info->sync_obj]); - if (signalable_row->state == CAM_SYNC_STATE_INVALID) { - spin_unlock_bh( - &sync_dev->row_spinlocks[list_info->sync_obj]); - continue; - } - - /* Dispatch kernel callbacks if any were registered earlier */ - - list_for_each_entry_safe(sync_cb, - temp_sync_cb, &signalable_row->callback_list, list) { - sync_cb->status = list_info->status; - list_del_init(&sync_cb->list); - queue_work(sync_dev->work_queue, - &sync_cb->cb_dispatch_work); - } - - /* Dispatch user payloads if any were registered earlier */ - list_for_each_entry_safe(payload_info, temp_payload_info, - &signalable_row->user_payload_list, list) { - spin_lock_bh(&sync_dev->cam_sync_eventq_lock); - if (!sync_dev->cam_sync_eventq) { - spin_unlock_bh( - &sync_dev->cam_sync_eventq_lock); - break; - } - spin_unlock_bh(&sync_dev->cam_sync_eventq_lock); - cam_sync_util_send_v4l2_event( - CAM_SYNC_V4L_EVENT_ID_CB_TRIG, - list_info->sync_obj, - list_info->status, - payload_info->payload_data, - CAM_SYNC_PAYLOAD_WORDS * sizeof(__u64)); - - list_del_init(&payload_info->list); - /* - * We can free the list node here because - * sending V4L event will make a deep copy - * anyway - */ - kfree(payload_info); - } - - /* - * This needs to be done because we want to unblock anyone - * who might be blocked and waiting on this sync object - */ - complete_all(&signalable_row->signaled); - - spin_unlock_bh(&sync_dev->row_spinlocks[list_info->sync_obj]); + if (!parent_row->remaining) + cam_sync_util_dispatch_signaled_cb( + parent_info->sync_id, parent_row->state); - list_del_init(&list_info->list); - kfree(list_info); + spin_unlock_bh(&sync_dev->row_spinlocks[parent_info->sync_id]); + list_del_init(&parent_info->list); + kfree(parent_info); } - return rc; + return 0; } int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj) @@ -965,6 +891,26 @@ static void cam_sync_init_entity(struct sync_device *sync_dev) } #endif +static int cam_sync_create_debugfs(void) +{ + sync_dev->dentry = debugfs_create_dir("camera_sync", NULL); + + if (!sync_dev->dentry) { + CAM_ERR(CAM_SYNC, "Failed to create sync dir"); + return -ENOMEM; + } + + if (!debugfs_create_bool("trigger_cb_without_switch", + 0644, sync_dev->dentry, + &trigger_cb_without_switch)) { + CAM_ERR(CAM_SYNC, + "failed to create trigger_cb_without_switch entry"); + return -ENOMEM; + } + + return 0; +} + static int cam_sync_probe(struct platform_device *pdev) { int rc; @@ -1030,6 +976,9 @@ static int cam_sync_probe(struct platform_device *pdev) goto v4l2_fail; } + trigger_cb_without_switch = false; + cam_sync_create_debugfs(); + return rc; v4l2_fail: @@ -1049,6 +998,8 @@ static int cam_sync_remove(struct platform_device *pdev) v4l2_device_unregister(sync_dev->vdev->v4l2_dev); cam_sync_media_controller_cleanup(sync_dev); video_device_release(sync_dev->vdev); + debugfs_remove_recursive(sync_dev->dentry); + sync_dev->dentry = NULL; kfree(sync_dev); sync_dev = NULL; diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h b/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h index 5ae707a2b6e7..38dab42a56cc 100644 --- a/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h +++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,6 +17,7 @@ #include <linux/videodev2.h> #include <linux/workqueue.h> #include <linux/interrupt.h> +#include <linux/debugfs.h> #include <media/v4l2-fh.h> #include <media/v4l2-device.h> #include <media/v4l2-subdev.h> @@ -177,6 +178,7 @@ struct cam_signalable_info { * @row_spinlocks : Spinlock array, one for each row in the table * @table_lock : Mutex used to lock the table * @open_cnt : Count of file open calls made on the sync driver + * @dentry : Debugfs entry * @work_queue : Work queue used for dispatching kernel callbacks * @cam_sync_eventq : Event queue used to dispatch user payloads to user space * @bitmap : Bitmap representation of all sync objects @@ -188,6 +190,7 @@ struct sync_device { spinlock_t row_spinlocks[CAM_SYNC_MAX_OBJS]; struct mutex table_lock; int open_cnt; + struct dentry *dentry; struct workqueue_struct *work_queue; struct v4l2_fh *cam_sync_eventq; spinlock_t cam_sync_eventq_lock; diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c b/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c index f391c8c8d51d..49a9d2f39974 100644 --- a/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c +++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c @@ -287,6 +287,64 @@ void cam_sync_util_cb_dispatch(struct work_struct *cb_dispatch_work) kfree(cb_info); } +void cam_sync_util_dispatch_signaled_cb(int32_t sync_obj, + uint32_t status) +{ + struct sync_callback_info *sync_cb; + struct sync_user_payload *payload_info; + struct sync_callback_info *temp_sync_cb; + struct sync_table_row *signalable_row; + struct sync_user_payload *temp_payload_info; + + signalable_row = sync_dev->sync_table + sync_obj; + if (signalable_row->state == CAM_SYNC_STATE_INVALID) { + CAM_DBG(CAM_SYNC, + "Accessing invalid sync object:%i", sync_obj); + return; + } + + /* Dispatch kernel callbacks if any were registered earlier */ + list_for_each_entry_safe(sync_cb, + temp_sync_cb, &signalable_row->callback_list, list) { + sync_cb->status = status; + list_del_init(&sync_cb->list); + queue_work(sync_dev->work_queue, + &sync_cb->cb_dispatch_work); + } + + /* Dispatch user payloads if any were registered earlier */ + list_for_each_entry_safe(payload_info, temp_payload_info, + &signalable_row->user_payload_list, list) { + spin_lock_bh(&sync_dev->cam_sync_eventq_lock); + if (!sync_dev->cam_sync_eventq) { + spin_unlock_bh( + &sync_dev->cam_sync_eventq_lock); + break; + } + spin_unlock_bh(&sync_dev->cam_sync_eventq_lock); + cam_sync_util_send_v4l2_event( + CAM_SYNC_V4L_EVENT_ID_CB_TRIG, + sync_obj, + status, + payload_info->payload_data, + CAM_SYNC_PAYLOAD_WORDS * sizeof(__u64)); + + list_del_init(&payload_info->list); + /* + * We can free the list node here because + * sending V4L event will make a deep copy + * anyway + */ + kfree(payload_info); + } + + /* + * This needs to be done because we want to unblock anyone + * who might be blocked and waiting on this sync object + */ + complete_all(&signalable_row->signaled); +} + void cam_sync_util_send_v4l2_event(uint32_t id, uint32_t sync_obj, int status, @@ -312,26 +370,6 @@ void cam_sync_util_send_v4l2_event(uint32_t id, sync_obj); } -int cam_sync_util_add_to_signalable_list(int32_t sync_obj, - uint32_t status, - struct list_head *sync_list) -{ - struct cam_signalable_info *signalable_info = NULL; - - signalable_info = kzalloc(sizeof(*signalable_info), GFP_ATOMIC); - if (!signalable_info) - return -ENOMEM; - - signalable_info->sync_obj = sync_obj; - signalable_info->status = status; - - list_add_tail(&signalable_info->list, sync_list); - CAM_DBG(CAM_SYNC, "Add sync_obj :%d with status :%d to signalable list", - sync_obj, status); - - return 0; -} - int cam_sync_util_update_parent_state(struct sync_table_row *parent_row, int new_state) { diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.h b/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.h index a9d6f86c1709..cfa450c0e744 100644 --- a/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.h +++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.h @@ -87,6 +87,17 @@ int cam_sync_deinit_object(struct sync_table_row *table, uint32_t idx); void cam_sync_util_cb_dispatch(struct work_struct *cb_dispatch_work); /** + * @brief: Function to dispatch callbacks for a signaled sync object + * + * @sync_obj : Sync object that is signaled + * @status : Status of the signaled object + * + * @return None + */ +void cam_sync_util_dispatch_signaled_cb(int32_t sync_obj, + uint32_t status); + +/** * @brief: Function to send V4L event to user space * @param id : V4L event id to send * @param sync_obj : Sync obj for which event needs to be sent @@ -103,19 +114,6 @@ void cam_sync_util_send_v4l2_event(uint32_t id, int len); /** - * @brief: Function which adds sync object information to the signalable list - * - * @param sync_obj : Sync object to add - * @param status : Status of above sync object - * @param list : Linked list where the information should be added to - * - * @return Status of operation. Negative in case of error. Zero otherwise. - */ -int cam_sync_util_add_to_signalable_list(int32_t sync_obj, - uint32_t status, - struct list_head *sync_list); - -/** * @brief: Function which gets the next state of the sync object based on the * current state and the new state * diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c index db2629d2a2f9..a88ccdb93641 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c +++ b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c @@ -127,7 +127,7 @@ int cam_packet_util_process_patches(struct cam_packet *packet, int32_t iommu_hdl, int32_t sec_mmu_hdl) { struct cam_patch_desc *patch_desc = NULL; - uint64_t iova_addr; + dma_addr_t iova_addr; uint64_t cpu_addr; uint32_t temp; uint32_t *dst_cpu_addr; diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 651d0a2968c7..815d137d98ec 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -1860,6 +1860,8 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "Failed to release mark_data buffers\n"); + msm_comm_free_buffer_tags(inst); + msm_comm_release_eos_buffers(inst); if (msm_comm_release_output_buffers(inst, true)) diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c index c15a2e9d12fc..802e58140d85 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c @@ -932,6 +932,12 @@ int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst) break; } } + + if (!inst->clk_data.entry) { + dprintk(VIDC_ERR, "%s No match found\n", __func__); + rc = -EINVAL; + } + return rc; } diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index b8789711d3eb..176b9c647290 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -3138,7 +3138,11 @@ static int msm_comm_session_init(int flipped_state, return -EINVAL; } - msm_comm_init_clocks_and_bus_data(inst); + rc = msm_comm_init_clocks_and_bus_data(inst); + if (rc) { + dprintk(VIDC_ERR, "Failed to initialize clocks and bus data\n"); + goto exit; + } dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data, diff --git a/drivers/media/platform/msm/vidc_3x/msm_vdec.c b/drivers/media/platform/msm/vidc_3x/msm_vdec.c index 04bdd65b898d..bb4b6c84f966 100644 --- a/drivers/media/platform/msm/vidc_3x/msm_vdec.c +++ b/drivers/media/platform/msm/vidc_3x/msm_vdec.c @@ -22,6 +22,7 @@ #define MSM_VDEC_DVC_NAME "msm_vdec_8974" #define MIN_NUM_OUTPUT_BUFFERS 4 #define MIN_NUM_OUTPUT_BUFFERS_VP9 6 +#define MIN_NUM_OUTPUT_BUFFERS_HEVC 6 #define MIN_NUM_CAPTURE_BUFFERS 6 #define MIN_NUM_THUMBNAIL_MODE_CAPTURE_BUFFERS 1 #define MAX_NUM_OUTPUT_BUFFERS VB2_MAX_FRAME @@ -1499,6 +1500,10 @@ static int msm_vdec_queue_setup(struct vb2_queue *q, V4L2_PIX_FMT_VP9 && *num_buffers < MIN_NUM_OUTPUT_BUFFERS_VP9) *num_buffers = MIN_NUM_OUTPUT_BUFFERS_VP9; + else if (inst->fmts[OUTPUT_PORT].fourcc == + V4L2_PIX_FMT_HEVC && + *num_buffers < MIN_NUM_OUTPUT_BUFFERS_HEVC) + *num_buffers = MIN_NUM_OUTPUT_BUFFERS_HEVC; for (i = 0; i < *num_planes; i++) { sizes[i] = get_frame_size(inst, diff --git a/drivers/media/platform/msm/vidc_3x/venus_hfi.c b/drivers/media/platform/msm/vidc_3x/venus_hfi.c index b83606a897cb..1bd6ae8959cf 100644 --- a/drivers/media/platform/msm/vidc_3x/venus_hfi.c +++ b/drivers/media/platform/msm/vidc_3x/venus_hfi.c @@ -1587,7 +1587,7 @@ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, __strict_check(device); if (!__core_in_valid_state(device)) { - dprintk(VIDC_DBG, "%s - fw not in init state\n", __func__); + dprintk(VIDC_ERR, "%s - fw not in init state\n", __func__); result = -EINVAL; goto err_q_null; } @@ -3337,8 +3337,6 @@ static void __process_sys_error(struct venus_hfi_device *device) { struct hfi_sfr_struct *vsfr = NULL; - __set_state(device, VENUS_STATE_DEINIT); - /* Once SYS_ERROR received from HW, it is safe to halt the AXI. * With SYS_ERROR, Venus FW may have crashed and HW might be * active and causing unnecessary transactions. Hence it is @@ -3581,6 +3579,9 @@ static int __response_handler(struct venus_hfi_device *device) "Too many packets in message queue to handle at once, deferring read\n"); break; } + /* do not read packets after sys error packet */ + if (info->response_type == HAL_SYS_ERROR) + break; } if (requeue_pm_work && device->res->sw_power_collapsible) { @@ -3644,6 +3645,12 @@ err_no_work: i < num_responses; ++i) { struct msm_vidc_cb_info *r = &device->response_pkt[i]; + if (!__core_in_valid_state(device)) { + dprintk(VIDC_ERR, + "Ignore responses from %d to %d as device is in invalid state", + (i + 1), num_responses); + break; + } device->callback(r->response_type, &r->response); } diff --git a/drivers/net/wireless/cnss_prealloc/cnss_prealloc.c b/drivers/net/wireless/cnss_prealloc/cnss_prealloc.c index c09e61fe83d7..7eb2a070fd89 100644 --- a/drivers/net/wireless/cnss_prealloc/cnss_prealloc.c +++ b/drivers/net/wireless/cnss_prealloc/cnss_prealloc.c @@ -173,8 +173,6 @@ void *wcnss_prealloc_get(unsigned int size) } spin_unlock_irqrestore(&alloc_lock, flags); - WARN(1, "wcnss_prealloc not available for size %d\n", size); - return NULL; } EXPORT_SYMBOL(wcnss_prealloc_get); diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c index 0b8c212c84fe..37ae308afe5a 100644 --- a/drivers/power/reset/msm-poweroff.c +++ b/drivers/power/reset/msm-poweroff.c @@ -50,20 +50,23 @@ #define SCM_DLOAD_BOTHDUMPS (SCM_DLOAD_MINIDUMP | SCM_DLOAD_FULLDUMP) static int restart_mode; -static void __iomem *restart_reason, *dload_type_addr; +static void *restart_reason; static bool scm_pmic_arbiter_disable_supported; static bool scm_deassert_ps_hold_supported; /* Download mode master kill-switch */ static void __iomem *msm_ps_hold; static phys_addr_t tcsr_boot_misc_detect; +static void scm_disable_sdi(void); + +#ifdef CONFIG_QCOM_DLOAD_MODE /* Runtime could be only changed value once. * There is no API from TZ to re-enable the registers. * So the SDI cannot be re-enabled when it already by-passed. */ static int download_mode = 1; -static struct kobject dload_kobj; -static void scm_disable_sdi(void); - +#else +static const int download_mode; +#endif #ifdef CONFIG_QCOM_DLOAD_MODE #define EDL_MODE_PROP "qcom,msm-imem-emergency_download_mode" @@ -81,6 +84,8 @@ static void *emergency_dload_mode_addr; static void *kaslr_imem_addr; #endif static bool scm_dload_supported; +static struct kobject dload_kobj; +static void *dload_type_addr; static int dload_set(const char *val, const struct kernel_param *kp); /* interface for exporting attributes */ @@ -431,6 +436,7 @@ static void do_msm_poweroff(void) pr_err("Powering off has failed\n"); } +#ifdef CONFIG_QCOM_DLOAD_MODE static ssize_t attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { @@ -561,6 +567,7 @@ static struct attribute *reset_attrs[] = { static struct attribute_group reset_attr_group = { .attrs = reset_attrs, }; +#endif static int msm_restart_probe(struct platform_device *pdev) { diff --git a/drivers/power/supply/qcom/qpnp-linear-charger.c b/drivers/power/supply/qcom/qpnp-linear-charger.c index 7815eba3209b..dff51dfb5e20 100644 --- a/drivers/power/supply/qcom/qpnp-linear-charger.c +++ b/drivers/power/supply/qcom/qpnp-linear-charger.c @@ -1472,6 +1472,9 @@ static int qpnp_lbc_configure_jeita(struct qpnp_lbc_chip *chip, return -EINVAL; } + if (chip->cfg_use_fake_battery) + return 0; + mutex_lock(&chip->jeita_configure_lock); switch (psp) { case POWER_SUPPLY_PROP_COOL_TEMP: @@ -2634,15 +2637,15 @@ static irqreturn_t qpnp_lbc_batt_pres_irq_handler(int irq, void *_chip) power_supply_changed(chip->batt_psy); if ((chip->cfg_cool_bat_decidegc - || chip->cfg_warm_bat_decidegc) - && batt_present) { + || chip->cfg_warm_bat_decidegc) + && batt_present && !chip->cfg_use_fake_battery) { pr_debug("enabling vadc notifications\n"); if (qpnp_adc_tm_channel_measure(chip->adc_tm_dev, &chip->adc_param)) pr_err("request ADC error\n"); } else if ((chip->cfg_cool_bat_decidegc - || chip->cfg_warm_bat_decidegc) - && !batt_present) { + || chip->cfg_warm_bat_decidegc) + && !batt_present && !chip->cfg_use_fake_battery) { qpnp_adc_tm_disable_chan_meas(chip->adc_tm_dev, &chip->adc_param); pr_debug("disabling vadc notifications\n"); @@ -3398,7 +3401,7 @@ static int qpnp_lbc_main_probe(struct platform_device *pdev) } if ((chip->cfg_cool_bat_decidegc || chip->cfg_warm_bat_decidegc) - && chip->bat_if_base) { + && chip->bat_if_base && !chip->cfg_use_fake_battery) { chip->adc_param.low_temp = chip->cfg_cool_bat_decidegc; chip->adc_param.high_temp = chip->cfg_warm_bat_decidegc; chip->adc_param.timer_interval = ADC_MEAS1_INTERVAL_1S; diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c index e56ecb0f992f..57aa0c6de742 100644 --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -1785,27 +1785,31 @@ static int smb5_configure_micro_usb(struct smb_charger *chg) static int smb5_configure_mitigation(struct smb_charger *chg) { int rc; - u8 chan = 0; + u8 chan = 0, src_cfg = 0; if (!chg->hw_die_temp_mitigation && !chg->hw_connector_mitigation) return 0; if (chg->hw_die_temp_mitigation) { - rc = smblib_write(chg, MISC_THERMREG_SRC_CFG_REG, - THERMREG_CONNECTOR_ADC_SRC_EN_BIT - | THERMREG_DIE_ADC_SRC_EN_BIT - | THERMREG_DIE_CMP_SRC_EN_BIT); - if (rc < 0) { - dev_err(chg->dev, - "Couldn't configure THERM_SRC reg rc=%d\n", rc); - return rc; - }; - chan = DIE_TEMP_CHANNEL_EN_BIT; + src_cfg = THERMREG_DIE_ADC_SRC_EN_BIT + | THERMREG_DIE_CMP_SRC_EN_BIT; } - if (chg->hw_connector_mitigation) + if (chg->hw_connector_mitigation) { chan |= CONN_THM_CHANNEL_EN_BIT; + src_cfg |= THERMREG_CONNECTOR_ADC_SRC_EN_BIT; + } + + rc = smblib_masked_write(chg, MISC_THERMREG_SRC_CFG_REG, + THERMREG_SW_ICL_ADJUST_BIT | THERMREG_DIE_ADC_SRC_EN_BIT + | THERMREG_DIE_CMP_SRC_EN_BIT + | THERMREG_CONNECTOR_ADC_SRC_EN_BIT, src_cfg); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't configure THERM_SRC reg rc=%d\n", rc); + return rc; + }; rc = smblib_masked_write(chg, BATIF_ADC_CHANNEL_EN_REG, CONN_THM_CHANNEL_EN_BIT | DIE_TEMP_CHANNEL_EN_BIT, diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 6b6bc9c327aa..5546eae92663 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -510,6 +510,9 @@ static int smblib_request_dpdm(struct smb_charger *chg, bool enable) { int rc = 0; + if (chg->pr_swap_in_progress) + return 0; + /* fetch the DPDM regulator */ if (!chg->dpdm_reg && of_get_property(chg->dev->of_node, "dpdm-supply", NULL)) { diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c index 3b4b2754bc78..3e8b46b9e12b 100644 --- a/drivers/power/supply/qcom/step-chg-jeita.c +++ b/drivers/power/supply/qcom/step-chg-jeita.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -79,10 +79,12 @@ struct step_chg_info { struct votable *fcc_votable; struct votable *fv_votable; + struct votable *usb_icl_votable; struct wakeup_source *step_chg_ws; struct power_supply *batt_psy; struct power_supply *bms_psy; struct power_supply *main_psy; + struct power_supply *usb_psy; struct delayed_work status_change_work; struct delayed_work get_config_work; struct notifier_block nb; @@ -119,6 +121,17 @@ static bool is_bms_available(struct step_chg_info *chip) return true; } +static bool is_usb_available(struct step_chg_info *chip) +{ + if (!chip->usb_psy) + chip->usb_psy = power_supply_get_by_name("usb"); + + if (!chip->usb_psy) + return false; + + return true; +} + static int read_range_data_from_node(struct device_node *node, const char *prop_str, struct range_data *ranges, u32 max_threshold, u32 max_value) @@ -486,6 +499,7 @@ reschedule: return (STEP_CHG_HYSTERISIS_DELAY_US - elapsed_us + 1000); } +#define JEITA_SUSPEND_HYST_UV 50000 static int handle_jeita(struct step_chg_info *chip) { union power_supply_propval pval = {0, }; @@ -504,6 +518,8 @@ static int handle_jeita(struct step_chg_info *chip) vote(chip->fcc_votable, JEITA_VOTER, false, 0); if (chip->fv_votable) vote(chip->fv_votable, JEITA_VOTER, false, 0); + if (chip->usb_icl_votable) + vote(chip->usb_icl_votable, JEITA_VOTER, false, 0); return 0; } @@ -525,12 +541,8 @@ static int handle_jeita(struct step_chg_info *chip) pval.intval, &chip->jeita_fcc_index, &fcc_ua); - if (rc < 0) { - /* remove the vote if no step-based fcc is found */ - if (chip->fcc_votable) - vote(chip->fcc_votable, JEITA_VOTER, false, 0); - goto update_time; - } + if (rc < 0) + fcc_ua = 0; if (!chip->fcc_votable) chip->fcc_votable = find_votable("FCC"); @@ -538,7 +550,7 @@ static int handle_jeita(struct step_chg_info *chip) /* changing FCC is a must */ return -EINVAL; - vote(chip->fcc_votable, JEITA_VOTER, true, fcc_ua); + vote(chip->fcc_votable, JEITA_VOTER, fcc_ua ? true : false, fcc_ua); rc = get_val(chip->jeita_fv_config->fv_cfg, chip->jeita_fv_config->hysteresis, @@ -546,21 +558,45 @@ static int handle_jeita(struct step_chg_info *chip) pval.intval, &chip->jeita_fv_index, &fv_uv); - if (rc < 0) { - /* remove the vote if no step-based fcc is found */ - if (chip->fv_votable) - vote(chip->fv_votable, JEITA_VOTER, false, 0); - goto update_time; - } + if (rc < 0) + fv_uv = 0; chip->fv_votable = find_votable("FV"); if (!chip->fv_votable) goto update_time; - vote(chip->fv_votable, JEITA_VOTER, true, fv_uv); + if (!chip->usb_icl_votable) + chip->usb_icl_votable = find_votable("USB_ICL"); + + if (!chip->usb_icl_votable) + goto set_jeita_fv; + + /* + * If JEITA float voltage is same as max-vfloat of battery then + * skip any further VBAT specific checks. + */ + rc = power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_VOLTAGE_MAX, &pval); + if (rc || (pval.intval == fv_uv)) { + vote(chip->usb_icl_votable, JEITA_VOTER, false, 0); + goto set_jeita_fv; + } - pr_debug("%s = %d FCC = %duA FV = %duV\n", - chip->jeita_fcc_config->prop_name, pval.intval, fcc_ua, fv_uv); + /* + * Suspend USB input path if battery voltage is above + * JEITA VFLOAT threshold. + */ + if (fv_uv > 0) { + rc = power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); + if (!rc && (pval.intval > fv_uv)) + vote(chip->usb_icl_votable, JEITA_VOTER, true, 0); + else if (pval.intval < (fv_uv - JEITA_SUSPEND_HYST_UV)) + vote(chip->usb_icl_votable, JEITA_VOTER, false, 0); + } + +set_jeita_fv: + vote(chip->fv_votable, JEITA_VOTER, fv_uv ? true : false, fv_uv); update_time: chip->jeita_last_update_time = ktime_get(); @@ -618,11 +654,13 @@ static void status_change_work(struct work_struct *work) int reschedule_us; int reschedule_jeita_work_us = 0; int reschedule_step_work_us = 0; + union power_supply_propval prop = {0, }; if (!is_batt_available(chip)) - return; + goto exit_work; handle_battery_insertion(chip); + /* skip elapsed_us debounce for handling battery temperature */ rc = handle_jeita(chip); if (rc > 0) @@ -636,12 +674,28 @@ static void status_change_work(struct work_struct *work) if (rc < 0) pr_err("Couldn't handle step rc = %d\n", rc); + /* Remove stale votes on USB removal */ + if (is_usb_available(chip)) { + prop.intval = 0; + power_supply_get_property(chip->usb_psy, + POWER_SUPPLY_PROP_PRESENT, &prop); + if (!prop.intval) { + if (chip->usb_icl_votable) + vote(chip->usb_icl_votable, JEITA_VOTER, + false, 0); + } + } + reschedule_us = min(reschedule_jeita_work_us, reschedule_step_work_us); if (reschedule_us == 0) - __pm_relax(chip->step_chg_ws); + goto exit_work; else schedule_delayed_work(&chip->status_change_work, usecs_to_jiffies(reschedule_us)); + return; + +exit_work: + __pm_relax(chip->step_chg_ws); } static int step_chg_notifier_call(struct notifier_block *nb, @@ -653,7 +707,8 @@ static int step_chg_notifier_call(struct notifier_block *nb, if (ev != PSY_EVENT_PROP_CHANGED) return NOTIFY_OK; - if ((strcmp(psy->desc->name, "battery") == 0)) { + if ((strcmp(psy->desc->name, "battery") == 0) + || (strcmp(psy->desc->name, "usb") == 0)) { __pm_stay_awake(chip->step_chg_ws); schedule_delayed_work(&chip->status_change_work, 0); } diff --git a/drivers/regulator/qpnp-lcdb-regulator.c b/drivers/regulator/qpnp-lcdb-regulator.c index 4e8d6f97b6a4..a0f0fcec9cdf 100644 --- a/drivers/regulator/qpnp-lcdb-regulator.c +++ b/drivers/regulator/qpnp-lcdb-regulator.c @@ -1151,6 +1151,7 @@ static int qpnp_lcdb_get_voltage(struct qpnp_lcdb *lcdb, return rc; } + val &= SET_OUTPUT_VOLTAGE_MASK; if (val < VOLTAGE_STEP_50MV_OFFSET) { *voltage_mv = VOLTAGE_MIN_STEP_100_MV + (val * VOLTAGE_STEP_100_MV); @@ -1826,7 +1827,7 @@ static int qpnp_lcdb_init_bst(struct qpnp_lcdb *lcdb) if (lcdb->bst.pd_strength != -EINVAL) { rc = qpnp_lcdb_masked_write(lcdb, lcdb->base + - LCDB_NCP_PD_CTL_REG, BOOST_PD_STRENGTH_BIT, + LCDB_BST_PD_CTL_REG, BOOST_PD_STRENGTH_BIT, lcdb->bst.pd_strength ? BOOST_PD_STRENGTH_BIT : 0); if (rc < 0) { diff --git a/drivers/soc/qcom/bg_rsb.c b/drivers/soc/qcom/bg_rsb.c index ffba37205976..1b5830a557b8 100644 --- a/drivers/soc/qcom/bg_rsb.c +++ b/drivers/soc/qcom/bg_rsb.c @@ -83,6 +83,8 @@ struct bgrsb_priv { struct input_dev *input; struct mutex glink_mutex; + struct mutex rsb_state_mutex; + enum bgrsb_state bgrsb_current_state; enum glink_link_state link_state; @@ -651,9 +653,10 @@ static void bgrsb_enable_rsb(struct work_struct *work) struct bgrsb_priv *dev = container_of(work, struct bgrsb_priv, rsb_up_work); + mutex_lock(&dev->rsb_state_mutex); if (dev->bgrsb_current_state != BGRSB_STATE_RSB_CONFIGURED) { pr_err("BG is not yet configured for RSB\n"); - return; + goto unlock; } if (bgrsb_ldo_work(dev, BGRSB_ENABLE_LDO15) == 0) { @@ -663,7 +666,7 @@ static void bgrsb_enable_rsb(struct work_struct *work) pr_err("Failed to send enable command to BG\n"); bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15); dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED; - return; + goto unlock; } } dev->bgrsb_current_state = BGRSB_STATE_RSB_ENABLED; @@ -673,6 +676,9 @@ static void bgrsb_enable_rsb(struct work_struct *work) dev->calibration_needed = false; queue_work(dev->bgrsb_wq, &dev->rsb_calibration_work); } +unlock: + mutex_unlock(&dev->rsb_state_mutex); + } static void bgrsb_disable_rsb(struct work_struct *work) @@ -681,20 +687,24 @@ static void bgrsb_disable_rsb(struct work_struct *work) struct bgrsb_priv *dev = container_of(work, struct bgrsb_priv, rsb_down_work); + mutex_lock(&dev->rsb_state_mutex); if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) { rc = bgrsb_enable(dev, false); if (rc != 0) { pr_err("Failed to send disable command to BG\n"); - return; + goto unlock; } if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15) != 0) - return; + goto unlock; dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED; pr_debug("RSB Disabled\n"); } + +unlock: + mutex_unlock(&dev->rsb_state_mutex); } static void bgrsb_calibration(struct work_struct *work) @@ -763,13 +773,9 @@ static int split_bg_work(struct bgrsb_priv *dev, char *str) switch (val) { case BGRSB_POWER_DISABLE: - if (dev->bgrsb_current_state == BGRSB_STATE_RSB_CONFIGURED) - return 0; queue_work(dev->bgrsb_wq, &dev->rsb_down_work); break; case BGRSB_POWER_ENABLE: - if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) - return 0; queue_work(dev->bgrsb_wq, &dev->rsb_up_work); break; case BGRSB_POWER_CALIBRATION: @@ -857,6 +863,7 @@ static int bgrsb_init(struct bgrsb_priv *dev) dev->chnl.chnl_edge = "bg"; dev->chnl.chnl_trnsprt = "bgcom"; mutex_init(&dev->glink_mutex); + mutex_init(&dev->rsb_state_mutex); dev->link_state = GLINK_LINK_STATE_DOWN; dev->ldo_action = BGRSB_NO_ACTION; @@ -981,18 +988,24 @@ static int bg_rsb_resume(struct device *pldev) struct platform_device *pdev = to_platform_device(pldev); struct bgrsb_priv *dev = platform_get_drvdata(pdev); + mutex_lock(&dev->rsb_state_mutex); if (dev->bgrsb_current_state == BGRSB_STATE_RSB_CONFIGURED) - return 0; + goto ret_success; if (dev->bgrsb_current_state == BGRSB_STATE_INIT) { if (bgrsb_ldo_work(dev, BGRSB_ENABLE_LDO11) == 0) { dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED; pr_debug("RSB Cofigured\n"); - return 0; + goto ret_success; } pr_err("RSB failed to resume\n"); } + mutex_unlock(&dev->rsb_state_mutex); return -EINVAL; + +ret_success: + mutex_unlock(&dev->rsb_state_mutex); + return 0; } static int bg_rsb_suspend(struct device *pldev) @@ -1000,8 +1013,9 @@ static int bg_rsb_suspend(struct device *pldev) struct platform_device *pdev = to_platform_device(pldev); struct bgrsb_priv *dev = platform_get_drvdata(pdev); + mutex_lock(&dev->rsb_state_mutex); if (dev->bgrsb_current_state == BGRSB_STATE_INIT) - return 0; + goto ret_success; if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) { if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15) != 0) @@ -1011,12 +1025,17 @@ static int bg_rsb_suspend(struct device *pldev) if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO11) == 0) { dev->bgrsb_current_state = BGRSB_STATE_INIT; pr_debug("RSB Init\n"); - return 0; + goto ret_success; } ret_err: pr_err("RSB failed to suspend\n"); + mutex_unlock(&dev->rsb_state_mutex); return -EINVAL; + +ret_success: + mutex_unlock(&dev->rsb_state_mutex); + return 0; } static const struct of_device_id bg_rsb_of_match[] = { diff --git a/drivers/soc/qcom/bgcom_spi.c b/drivers/soc/qcom/bgcom_spi.c index d21e2e944a91..7f8382a19c2d 100644 --- a/drivers/soc/qcom/bgcom_spi.c +++ b/drivers/soc/qcom/bgcom_spi.c @@ -1036,6 +1036,11 @@ static int bg_spi_remove(struct spi_device *spi) return 0; } +static void bg_spi_shutdown(struct spi_device *spi) +{ + bg_spi_remove(spi); +} + static int bgcom_pm_suspend(struct device *dev) { uint32_t cmnd_reg = 0; @@ -1090,6 +1095,7 @@ static struct spi_driver bg_spi_driver = { }, .probe = bg_spi_probe, .remove = bg_spi_remove, + .shutdown = bg_spi_shutdown, }; module_spi_driver(bg_spi_driver); diff --git a/drivers/soc/qcom/glink_bgcom_xprt.c b/drivers/soc/qcom/glink_bgcom_xprt.c index 290d6679a42f..9140ac1288c3 100644 --- a/drivers/soc/qcom/glink_bgcom_xprt.c +++ b/drivers/soc/qcom/glink_bgcom_xprt.c @@ -38,6 +38,8 @@ #define XPRT_NAME "bgcom" #define FIFO_ALIGNMENT 16 #define TRACER_PKT_FEATURE BIT(2) +#define SHORT_PKT_SIZE 16 +#define XPRT_ALIGNMENT 4 #define ACTIVE_TX BIT(0) #define ACTIVE_RX BIT(1) @@ -75,6 +77,7 @@ * @SIGNALS_CMD: Sideband signals * @TRACER_PKT_CMD: Start of a Tracer Packet Command * @TRACER_PKT_CONT_CMD: Continuation or end of a Tracer Packet Command + * @TX_SHORT_DATA_CMD: Transmit short packets */ enum command_types { VERSION_CMD, @@ -94,6 +97,7 @@ enum command_types { SIGNALS_CMD, TRACER_PKT_CMD, TRACER_PKT_CONT_CMD, + TX_SHORT_DATA_CMD, }; struct bgcom_fifo_size { @@ -381,7 +385,11 @@ static void process_rx_data(struct edge_info *einfo, uint16_t cmd_id, return; } - rc = bgcom_ahb_read(einfo->bgcom_handle, (uint32_t)(size_t)src, + + if (cmd_id == TX_SHORT_DATA_CMD) + memcpy(intent->data + intent->write_offset, src, frag_size); + else + rc = bgcom_ahb_read(einfo->bgcom_handle, (uint32_t)(size_t)src, ALIGN(frag_size, WORD_SIZE)/WORD_SIZE, intent->data + intent->write_offset); @@ -433,9 +441,13 @@ static void process_rx_cmd(struct edge_info *einfo, uint32_t size_left; uint64_t addr; }; + struct rx_short_data_desc { + unsigned char data[SHORT_PKT_SIZE]; + }; struct command *cmd; struct intent_desc *intents; struct rx_desc *rx_descp; + struct rx_short_data_desc *rx_sd_descp; int offset = 0; int rcu_id; uint16_t rcid; @@ -538,6 +550,15 @@ static void process_rx_cmd(struct edge_info *einfo, rx_descp->size, rx_descp->size_left); break; + case TX_SHORT_DATA_CMD: + rx_sd_descp = (struct rx_short_data_desc *) + (rx_data + offset); + offset += sizeof(*rx_sd_descp); + process_rx_data(einfo, cmd->id, cmd->param1, + cmd->param2, (void *)rx_sd_descp->data, + cmd->param3, cmd->param4); + break; + case READ_NOTIF_CMD: break; @@ -1267,6 +1288,8 @@ static int tx_data(struct glink_transport_if *if_ptr, uint16_t cmd_id, srcu_read_unlock(&einfo->use_ref, rcu_id); return -EINVAL; } + if (tx_size & (XPRT_ALIGNMENT - 1)) + tx_size = ALIGN(tx_size - SHORT_PKT_SIZE, XPRT_ALIGNMENT); if (likely(pctx->cookie)) dst = pctx->cookie + (pctx->size - pctx->size_remaining); @@ -1301,6 +1324,82 @@ static int tx_data(struct glink_transport_if *if_ptr, uint16_t cmd_id, } /** + * tx_short_data() - Tansmit a short packet in band along with command + * @if_ptr: The transport to transmit on. + * @cmd_id: The command ID to transmit. + * @lcid: The local channel id to encode. + * @pctx: The data to encode. + * + * Return: Number of bytes written or standard Linux error code. + */ +static int tx_short_data(struct glink_transport_if *if_ptr, + uint32_t lcid, struct glink_core_tx_pkt *pctx) +{ + struct command { + uint16_t id; + uint16_t lcid; + uint32_t riid; + uint32_t size; + uint32_t size_left; + unsigned char data[SHORT_PKT_SIZE]; + }; + struct command cmd; + struct edge_info *einfo; + void *data_start; + size_t tx_size = 0; + int rcu_id; + + if (pctx->size < pctx->size_remaining) { + GLINK_ERR("%s: size remaining exceeds size. Resetting.\n", + __func__); + pctx->size_remaining = pctx->size; + } + if (!pctx->size_remaining) + return 0; + + memset(&cmd, 0, sizeof(cmd)); + einfo = container_of(if_ptr, struct edge_info, xprt_if); + + rcu_id = srcu_read_lock(&einfo->use_ref); + if (einfo->in_ssr) { + srcu_read_unlock(&einfo->use_ref, rcu_id); + return -EFAULT; + } + + cmd.id = TX_SHORT_DATA_CMD; + cmd.lcid = lcid; + cmd.riid = pctx->riid; + data_start = get_tx_vaddr(pctx, pctx->size - pctx->size_remaining, + &tx_size); + if (unlikely(!data_start || tx_size > SHORT_PKT_SIZE)) { + GLINK_ERR("%s: invalid data_start %pK or tx_size %zu\n", + __func__, data_start, tx_size); + srcu_read_unlock(&einfo->use_ref, rcu_id); + return -EINVAL; + } + + mutex_lock(&einfo->write_lock); + if (glink_bgcom_get_tx_avail(einfo) <= sizeof(cmd)/WORD_SIZE) { + einfo->tx_resume_needed = true; + mutex_unlock(&einfo->write_lock); + srcu_read_unlock(&einfo->use_ref, rcu_id); + return -EAGAIN; + } + cmd.size = tx_size; + pctx->size_remaining -= tx_size; + cmd.size_left = pctx->size_remaining; + memcpy(cmd.data, data_start, tx_size); + bgcom_resume(einfo->bgcom_handle); + glink_bgcom_xprt_tx_cmd_safe(einfo, &cmd, sizeof(cmd)); + GLINK_DBG("%s %s: lcid[%u] riid[%u] cmd[%d], size[%d], size_left[%d]\n", + "<SPI>", __func__, cmd.lcid, cmd.riid, cmd.id, cmd.size, + cmd.size_left); + mutex_unlock(&einfo->write_lock); + srcu_read_unlock(&einfo->use_ref, rcu_id); + return cmd.size; +} + +/** * tx() - convert a data transmit cmd to wire format and transmit * @if_ptr: The transport to transmit on. * @lcid: The local channel id to encode. @@ -1311,6 +1410,8 @@ static int tx_data(struct glink_transport_if *if_ptr, uint16_t cmd_id, static int tx(struct glink_transport_if *if_ptr, uint32_t lcid, struct glink_core_tx_pkt *pctx) { + if (pctx->size_remaining <= SHORT_PKT_SIZE) + return tx_short_data(if_ptr, lcid, pctx); return tx_data(if_ptr, TX_DATA_CMD, lcid, pctx); } diff --git a/drivers/soc/qcom/secure_buffer.c b/drivers/soc/qcom/secure_buffer.c index 1c8bc5112256..5b82c0b25d38 100644 --- a/drivers/soc/qcom/secure_buffer.c +++ b/drivers/soc/qcom/secure_buffer.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Google, Inc - * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -142,7 +142,8 @@ static int secure_buffer_change_table(struct sg_table *table, int lock) * secure environment to ensure the data is actually present * in RAM */ - dmac_flush_range(chunk_list, chunk_list + chunk_list_len); + dmac_flush_range(chunk_list, + (void *)chunk_list + chunk_list_len); ret = secure_buffer_change_chunk(chunk_list_phys, nchunks, V2_CHUNK_SIZE, lock); diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index 492a93deeb88..09bae0345a26 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -160,7 +160,9 @@ static struct ion_heap_ops carveout_heap_ops = { .unmap_kernel = ion_heap_unmap_kernel, }; -struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) +static struct ion_heap *__ion_carveout_heap_create( + struct ion_platform_heap *heap_data, + bool sync) { struct ion_carveout_heap *carveout_heap; int ret; @@ -172,7 +174,8 @@ struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) page = pfn_to_page(PFN_DOWN(heap_data->base)); size = heap_data->size; - ion_pages_sync_for_device(dev, page, size, DMA_BIDIRECTIONAL); + if (sync) + ion_pages_sync_for_device(dev, page, size, DMA_BIDIRECTIONAL); ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); if (ret) @@ -197,6 +200,11 @@ struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) return &carveout_heap->heap; } +struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) +{ + return __ion_carveout_heap_create(heap_data, true); +} + void ion_carveout_heap_destroy(struct ion_heap *heap) { struct ion_carveout_heap *carveout_heap = @@ -362,7 +370,7 @@ static int ion_sc_add_child(struct ion_sc_heap *manager, heap_data.size = size; /* This will zero memory initially */ - entry->heap = ion_carveout_heap_create(&heap_data); + entry->heap = __ion_carveout_heap_create(&heap_data, false); if (IS_ERR(entry->heap)) goto out_free; diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 9bcfa38e893c..48017085567b 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1340,7 +1340,7 @@ static void gsi_set_clear_dbell(struct usb_ep *ep, */ static bool gsi_check_ready_to_suspend(struct usb_ep *ep, bool f_suspend) { - u32 timeout = 1500; + u32 timeout = 500; u32 reg = 0; struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; @@ -1353,6 +1353,7 @@ static bool gsi_check_ready_to_suspend(struct usb_ep *ep, bool f_suspend) "Unable to suspend GSI ch. WR_CTRL_STATE != 0\n"); return false; } + usleep_range(20, 22); } /* Check for U3 only if we are not handling Function Suspend */ if (!f_suspend) { @@ -2142,6 +2143,7 @@ static int dwc3_msm_prepare_suspend(struct dwc3_msm *mdwc) reg = dwc3_msm_read_reg(mdwc->base, PWR_EVNT_IRQ_STAT_REG); if (reg & PWR_EVNT_LPM_IN_L2_MASK) break; + usleep_range(20, 30); } if (!(reg & PWR_EVNT_LPM_IN_L2_MASK)) dev_err(mdwc->dev, "could not transition HS PHY to L2\n"); diff --git a/drivers/usb/gadget/function/f_qc_rndis.c b/drivers/usb/gadget/function/f_qc_rndis.c index df26403e1a31..dddf89ea41f5 100644 --- a/drivers/usb/gadget/function/f_qc_rndis.c +++ b/drivers/usb/gadget/function/f_qc_rndis.c @@ -6,7 +6,7 @@ * Copyright (C) 2008 Nokia Corporation * Copyright (C) 2009 Samsung Electronics * Author: Michal Nazarewicz (mina86@mina86.com) - * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -913,6 +913,13 @@ rndis_qc_bind(struct usb_configuration *c, struct usb_function *f) int status; struct usb_ep *ep; + status = rndis_ipa_init(&rndis_ipa_params); + if (status) { + pr_err("%s: failed to init rndis_ipa\n", __func__); + return status; + } + + rndis_ipa_supported = true; /* maybe allocate device-global string IDs */ if (rndis_qc_string_defs[0].id == 0) { @@ -1196,11 +1203,8 @@ usb_function *rndis_qc_bind_config_vendor(struct usb_function_instance *fi, struct f_rndis_qc_opts *opts = container_of(fi, struct f_rndis_qc_opts, func_inst); struct f_rndis_qc *rndis; - int status; /* allocate and initialize one new instance */ - status = -ENOMEM; - opts = container_of(fi, struct f_rndis_qc_opts, func_inst); opts->refcnt++; @@ -1214,7 +1218,6 @@ usb_function *rndis_qc_bind_config_vendor(struct usb_function_instance *fi, pr_debug("setting host_ethaddr=%pM, device_ethaddr=%pM\n", rndis_ipa_params.host_ethaddr, rndis_ipa_params.device_ethaddr); - rndis_ipa_supported = true; ether_addr_copy(rndis->ethaddr, rndis_ipa_params.host_ethaddr); rndis_ipa_params.device_ready_notify = rndis_net_ready_notify; @@ -1256,19 +1259,9 @@ usb_function *rndis_qc_bind_config_vendor(struct usb_function_instance *fi, rndis->func.resume = rndis_qc_resume; rndis->func.free_func = rndis_qc_free; - status = rndis_ipa_init(&rndis_ipa_params); - if (status) { - pr_err("%s: failed to init rndis_ipa\n", __func__); - goto fail; - } - _rndis_qc = rndis; return &rndis->func; -fail: - kfree(rndis); - _rndis_qc = NULL; - return ERR_PTR(status); } static struct usb_function *qcrndis_alloc(struct usb_function_instance *fi) diff --git a/drivers/video/fbdev/msm/mdss_compat_utils.c b/drivers/video/fbdev/msm/mdss_compat_utils.c index 23d4a27233d1..4ee8e603b8b5 100644 --- a/drivers/video/fbdev/msm/mdss_compat_utils.c +++ b/drivers/video/fbdev/msm/mdss_compat_utils.c @@ -1336,10 +1336,10 @@ static int __from_user_pgc_lut_data_legacy( return -EFAULT; if (num_r_stages > GC_LUT_SEGMENTS || num_b_stages > GC_LUT_SEGMENTS - || num_r_stages > GC_LUT_SEGMENTS || !num_r_stages || !num_b_stages + || num_g_stages > GC_LUT_SEGMENTS || !num_r_stages || !num_b_stages || !num_g_stages) { pr_err("invalid number of stages r_stages %d b_stages %d g_stages %d\n", - num_r_stages, num_b_stages, num_r_stages); + num_r_stages, num_b_stages, num_g_stages); return -EFAULT; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index bbffc0635cf9..029634bd06d3 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -5825,7 +5825,8 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, /* update backlight in commit */ if (ctl->intf_type == MDSS_INTF_DSI && !ctl->is_video_mode && - ctl->mfd && ctl->mfd->bl_extn_level > 0) { + ctl->mfd && ctl->mfd->bl_extn_level > 0 && + ctl->mfd->bl_extn_level != U64_MAX) { if (!IS_CALIB_MODE_BL(ctl->mfd) && (!ctl->mfd->ext_bl_ctrl || !ctl->mfd->bl_level)) { mutex_lock(&ctl->mfd->bl_lock); diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index 0ffe89c724c4..8c5f407c6510 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -2142,10 +2142,6 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) mdss_fb_report_panel_dead(ctl->mfd); } else if (ctx->pp_timeout_report_cnt == 0) { MDSS_XLOG(0xbad); - MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl", "dsi0_phy", - "dsi1_ctrl", "dsi1_phy", "vbif", "vbif_nrt", - "dbg_bus", "vbif_dbg_bus", - "dsi_dbg_bus", "panic"); } else if (ctx->pp_timeout_report_cnt == MAX_RECOVERY_TRIALS) { MDSS_XLOG(0xbad2); MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl", "dsi0_phy", diff --git a/include/linux/irq_sim.h b/include/linux/irq_sim.h new file mode 100644 index 000000000000..0380d899b955 --- /dev/null +++ b/include/linux/irq_sim.h @@ -0,0 +1,44 @@ +#ifndef _LINUX_IRQ_SIM_H +#define _LINUX_IRQ_SIM_H +/* + * Copyright (C) 2017 Bartosz Golaszewski <brgl@bgdev.pl> + * + * 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 the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/irq_work.h> +#include <linux/device.h> + +/* + * Provides a framework for allocating simulated interrupts which can be + * requested like normal irqs and enqueued from process context. + */ + +struct irq_sim_work_ctx { + struct irq_work work; + int irq; +}; + +struct irq_sim_irq_ctx { + int irqnum; + bool enabled; +}; + +struct irq_sim { + struct irq_sim_work_ctx work_ctx; + int irq_base; + unsigned int irq_count; + struct irq_sim_irq_ctx *irqs; +}; + +int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs); +int devm_irq_sim_init(struct device *dev, struct irq_sim *sim, + unsigned int num_irqs); +void irq_sim_fini(struct irq_sim *sim); +void irq_sim_fire(struct irq_sim *sim, unsigned int offset); +int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset); + +#endif /* _LINUX_IRQ_SIM_H */ diff --git a/include/uapi/linux/msm_kgsl.h b/include/uapi/linux/msm_kgsl.h index 943ba9ec33f6..8ffef5936bc4 100644 --- a/include/uapi/linux/msm_kgsl.h +++ b/include/uapi/linux/msm_kgsl.h @@ -332,6 +332,8 @@ enum kgsl_timestamp_type { #define KGSL_PROP_UBWC_MODE 0x1B #define KGSL_PROP_DEVICE_QTIMER 0x20 #define KGSL_PROP_L3_PWR_CONSTRAINT 0x22 +#define KGSL_PROP_SECURE_BUFFER_ALIGNMENT 0x23 +#define KGSL_PROP_SECURE_CTXT_SUPPORT 0x24 struct kgsl_shadowprop { unsigned long gpuaddr; diff --git a/kernel/cpu.c b/kernel/cpu.c index 3f3b7f848efe..aa035154bb72 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -521,7 +521,6 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, if (ret) { st->target = prev_state; undo_cpu_up(cpu, st); - cpu_notify(CPU_UP_CANCELED, cpu); break; } } @@ -1381,7 +1380,6 @@ static struct cpuhp_step cpuhp_bp_states[] = { .name = "notify:prepare", .startup.single = notify_prepare, .teardown.single = notify_dead, - .skip_onerr = true, .cant_stop = true, }, /* @@ -1487,7 +1485,6 @@ static struct cpuhp_step cpuhp_ap_states[] = { .name = "notify:online", .startup.single = notify_online, .teardown.single = notify_down_prepare, - .skip_onerr = true, }, #endif /* diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index 3bbfd6a9c475..9b2d34f6887b 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -59,6 +59,11 @@ config GENERIC_IRQ_CHIP config IRQ_DOMAIN bool +# Support for simulated interrupts +config IRQ_SIM + bool + select IRQ_WORK + # Support for hierarchical irq domains config IRQ_DOMAIN_HIERARCHY bool diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile index 1d3ee3169202..2c0ba4e66023 100644 --- a/kernel/irq/Makefile +++ b/kernel/irq/Makefile @@ -3,6 +3,7 @@ obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devr obj-$(CONFIG_GENERIC_IRQ_CHIP) += generic-chip.o obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o obj-$(CONFIG_IRQ_DOMAIN) += irqdomain.o +obj-$(CONFIG_IRQ_SIM) += irq_sim.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o obj-$(CONFIG_GENERIC_IRQ_MIGRATION) += cpuhotplug.o diff --git a/kernel/irq/irq_sim.c b/kernel/irq/irq_sim.c new file mode 100644 index 000000000000..85690859a2a8 --- /dev/null +++ b/kernel/irq/irq_sim.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2017 Bartosz Golaszewski <brgl@bgdev.pl> + * + * 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 the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/slab.h> +#include <linux/irq_sim.h> +#include <linux/irq.h> + +struct irq_sim_devres { + struct irq_sim *sim; +}; + +static void irq_sim_irqmask(struct irq_data *data) +{ + struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data); + + irq_ctx->enabled = false; +} + +static void irq_sim_irqunmask(struct irq_data *data) +{ + struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data); + + irq_ctx->enabled = true; +} + +static struct irq_chip irq_sim_irqchip = { + .name = "irq_sim", + .irq_mask = irq_sim_irqmask, + .irq_unmask = irq_sim_irqunmask, +}; + +static void irq_sim_handle_irq(struct irq_work *work) +{ + struct irq_sim_work_ctx *work_ctx; + + work_ctx = container_of(work, struct irq_sim_work_ctx, work); + handle_simple_irq(irq_to_desc(work_ctx->irq)); +} + +/** + * irq_sim_init - Initialize the interrupt simulator: allocate a range of + * dummy interrupts. + * + * @sim: The interrupt simulator object to initialize. + * @num_irqs: Number of interrupts to allocate + * + * On success: return the base of the allocated interrupt range. + * On failure: a negative errno. + */ +int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs) +{ + int i; + + sim->irqs = kmalloc_array(num_irqs, sizeof(*sim->irqs), GFP_KERNEL); + if (!sim->irqs) + return -ENOMEM; + + sim->irq_base = irq_alloc_descs(-1, 0, num_irqs, 0); + if (sim->irq_base < 0) { + kfree(sim->irqs); + return sim->irq_base; + } + + for (i = 0; i < num_irqs; i++) { + sim->irqs[i].irqnum = sim->irq_base + i; + sim->irqs[i].enabled = false; + irq_set_chip(sim->irq_base + i, &irq_sim_irqchip); + irq_set_chip_data(sim->irq_base + i, &sim->irqs[i]); + irq_set_handler(sim->irq_base + i, &handle_simple_irq); + irq_modify_status(sim->irq_base + i, + IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE); + } + + init_irq_work(&sim->work_ctx.work, irq_sim_handle_irq); + sim->irq_count = num_irqs; + + return sim->irq_base; +} +EXPORT_SYMBOL_GPL(irq_sim_init); + +/** + * irq_sim_fini - Deinitialize the interrupt simulator: free the interrupt + * descriptors and allocated memory. + * + * @sim: The interrupt simulator to tear down. + */ +void irq_sim_fini(struct irq_sim *sim) +{ + irq_work_sync(&sim->work_ctx.work); + irq_free_descs(sim->irq_base, sim->irq_count); + kfree(sim->irqs); +} +EXPORT_SYMBOL_GPL(irq_sim_fini); + +static void devm_irq_sim_release(struct device *dev, void *res) +{ + struct irq_sim_devres *this = res; + + irq_sim_fini(this->sim); +} + +/** + * irq_sim_init - Initialize the interrupt simulator for a managed device. + * + * @dev: Device to initialize the simulator object for. + * @sim: The interrupt simulator object to initialize. + * @num_irqs: Number of interrupts to allocate + * + * On success: return the base of the allocated interrupt range. + * On failure: a negative errno. + */ +int devm_irq_sim_init(struct device *dev, struct irq_sim *sim, + unsigned int num_irqs) +{ + struct irq_sim_devres *dr; + int rv; + + dr = devres_alloc(devm_irq_sim_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + rv = irq_sim_init(sim, num_irqs); + if (rv < 0) { + devres_free(dr); + return rv; + } + + dr->sim = sim; + devres_add(dev, dr); + + return rv; +} +EXPORT_SYMBOL_GPL(devm_irq_sim_init); + +/** + * irq_sim_fire - Enqueue an interrupt. + * + * @sim: The interrupt simulator object. + * @offset: Offset of the simulated interrupt which should be fired. + */ +void irq_sim_fire(struct irq_sim *sim, unsigned int offset) +{ + if (sim->irqs[offset].enabled) { + sim->work_ctx.irq = irq_sim_irqnum(sim, offset); + irq_work_queue(&sim->work_ctx.work); + } +} +EXPORT_SYMBOL_GPL(irq_sim_fire); + +/** + * irq_sim_irqnum - Get the allocated number of a dummy interrupt. + * + * @sim: The interrupt simulator object. + * @offset: Offset of the simulated interrupt for which to retrieve + * the number. + */ +int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset) +{ + return sim->irqs[offset].irqnum; +} +EXPORT_SYMBOL_GPL(irq_sim_irqnum); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index de11b815ad0e..2839d86117a2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4678,7 +4678,7 @@ tracing_saved_tgids_read(struct file *file, char __user *ubuf, preempt_disable(); arch_spin_lock(&trace_cmdline_lock); - pids = kmalloc_array(savedcmd->cmdline_num, 2*sizeof(int), GFP_KERNEL); + pids = kmalloc_array(savedcmd->cmdline_num, 2*sizeof(int), GFP_ATOMIC); if (!pids) { arch_spin_unlock(&trace_cmdline_lock); preempt_enable(); diff --git a/net/core/sockev_nlmcast.c b/net/core/sockev_nlmcast.c index f238edbfb823..6bc3d7a5cdc6 100644 --- a/net/core/sockev_nlmcast.c +++ b/net/core/sockev_nlmcast.c @@ -36,7 +36,6 @@ static struct netlink_kernel_cfg nlcfg = { static void _sockev_event(unsigned long event, __u8 *evstr, int buflen) { - memset(evstr, 0, buflen); switch (event) { case SOCKEV_SOCKET: @@ -98,6 +97,9 @@ static int sockev_client_cb(struct notifier_block *nb, NETLINK_CB(skb).dst_group = SKNLGRP_SOCKEV; smsg = nlmsg_data(nlh); + + memset(smsg, 0, sizeof(struct sknlsockevmsg)); + smsg->pid = current->pid; _sockev_event(event, smsg->event, sizeof(smsg->event)); smsg->skfamily = sk->sk_family; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f00e7d339ff4..e0869504e817 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -11438,6 +11438,7 @@ static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info) return -EOPNOTSUPP; if (!info->attrs[NL80211_ATTR_MDID] || + !info->attrs[NL80211_ATTR_IE] || !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) return -EINVAL; diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index fc9c9b0ad5f6..63e40b5275a0 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -379,7 +379,7 @@ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, unsigned int rshift = mc->rshift; int max = mc->max; int min = mc->min; - unsigned int mask = (1 << (fls(min + max) - 1)) - 1; + unsigned int mask = (1U << (fls(min + max) - 1)) - 1; unsigned int val; int ret; @@ -424,7 +424,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, unsigned int rshift = mc->rshift; int max = mc->max; int min = mc->min; - unsigned int mask = (1 << (fls(min + max) - 1)) - 1; + unsigned int mask = (1U << (fls(min + max) - 1)) - 1; int err = 0; unsigned int val, val_mask, val2 = 0; |