]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Sun, 25 Dec 2022 03:33:08 +0000 (22:33 -0500)
committerSasha Levin <sashal@kernel.org>
Sun, 25 Dec 2022 03:33:08 +0000 (22:33 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
546 files changed:
queue-5.10/acct-fix-potential-integer-overflow-in-encode_comp_t.patch [new file with mode: 0644]
queue-5.10/acpica-fix-error-code-path-in-acpi_ds_call_control_m.patch [new file with mode: 0644]
queue-5.10/acpica-fix-use-after-free-in-acpi_ut_copy_ipackage_t.patch [new file with mode: 0644]
queue-5.10/alpha-fix-syscall-entry-in-audut_syscall-case.patch [new file with mode: 0644]
queue-5.10/alsa-asihpi-fix-missing-pci_disable_device.patch [new file with mode: 0644]
queue-5.10/alsa-mts64-fix-possible-null-ptr-defer-in-snd_mts64_.patch [new file with mode: 0644]
queue-5.10/alsa-pcm-fix-undefined-behavior-in-bit-shift-for-snd.patch [new file with mode: 0644]
queue-5.10/alsa-pcm-set-missing-stop_operating-flag-at-undoing-.patch [new file with mode: 0644]
queue-5.10/alsa-seq-fix-undefined-behavior-in-bit-shift-for-snd.patch [new file with mode: 0644]
queue-5.10/amdgpu-pm-prevent-array-underflow-in-vega20_odn_edit.patch [new file with mode: 0644]
queue-5.10/apparmor-fix-a-memleak-in-multi_transaction_new.patch [new file with mode: 0644]
queue-5.10/apparmor-fix-abi-check-to-include-v8-abi.patch [new file with mode: 0644]
queue-5.10/apparmor-fix-lockdep-warning-when-removing-a-namespa.patch [new file with mode: 0644]
queue-5.10/apparmor-fix-memleak-in-alloc_ns.patch [new file with mode: 0644]
queue-5.10/apparmor-use-pointer-to-struct-aa_label-for-lbs_cred.patch [new file with mode: 0644]
queue-5.10/arm-dts-armada-370-fix-assigned-addresses-for-every-.patch [new file with mode: 0644]
queue-5.10/arm-dts-armada-375-fix-assigned-addresses-for-every-.patch [new file with mode: 0644]
queue-5.10/arm-dts-armada-38x-fix-assigned-addresses-for-every-.patch [new file with mode: 0644]
queue-5.10/arm-dts-armada-38x-fix-compatible-string-for-gpios.patch [new file with mode: 0644]
queue-5.10/arm-dts-armada-39x-fix-assigned-addresses-for-every-.patch [new file with mode: 0644]
queue-5.10/arm-dts-armada-39x-fix-compatible-string-for-gpios.patch [new file with mode: 0644]
queue-5.10/arm-dts-armada-xp-fix-assigned-addresses-for-every-p.patch [new file with mode: 0644]
queue-5.10/arm-dts-dove-fix-assigned-addresses-for-every-pcie-r.patch [new file with mode: 0644]
queue-5.10/arm-dts-qcom-apq8064-fix-coresight-compatible.patch [new file with mode: 0644]
queue-5.10/arm-dts-spear600-fix-clcd-interrupt.patch [new file with mode: 0644]
queue-5.10/arm-dts-stm32-drop-stm32mp15xc.dtsi-from-avenger96.patch [new file with mode: 0644]
queue-5.10/arm-dts-stm32-fix-av96-wlan-regulator-gpio-property.patch [new file with mode: 0644]
queue-5.10/arm-dts-turris-omnia-add-ethernet-aliases.patch [new file with mode: 0644]
queue-5.10/arm-dts-turris-omnia-add-switch-port-6-node.patch [new file with mode: 0644]
queue-5.10/arm-mmp-fix-timer_read-delay.patch [new file with mode: 0644]
queue-5.10/arm64-dts-armada-3720-turris-mox-add-missing-interru.patch [new file with mode: 0644]
queue-5.10/arm64-dts-mediatek-mt6797-fix-26m-oscillator-unit-na.patch [new file with mode: 0644]
queue-5.10/arm64-dts-mediatek-pumpkin-common-fix-devicetree-war.patch [new file with mode: 0644]
queue-5.10/arm64-dts-mt2712-evb-fix-usb-vbus-regulators-unit-na.patch [new file with mode: 0644]
queue-5.10/arm64-dts-mt2712-evb-fix-vproc-fixed-regulators-unit.patch [new file with mode: 0644]
queue-5.10/arm64-dts-mt2712e-fix-unit-address-for-pinctrl-node.patch [new file with mode: 0644]
queue-5.10/arm64-dts-mt2712e-fix-unit_address_vs_reg-warning-fo.patch [new file with mode: 0644]
queue-5.10/arm64-dts-qcom-ipq6018-cp01-c1-use-blspi1-pins.patch [new file with mode: 0644]
queue-5.10/arm64-dts-qcom-msm8916-drop-mss-fallback-compatible.patch [new file with mode: 0644]
queue-5.10/arm64-dts-qcom-msm8996-fix-gpu-opp-table.patch [new file with mode: 0644]
queue-5.10/arm64-dts-qcom-sdm630-fix-uart1-pin-bias.patch [new file with mode: 0644]
queue-5.10/arm64-dts-qcom-sdm845-cheza-fix-ap-suspend-pin-bias.patch [new file with mode: 0644]
queue-5.10/arm64-dts-ti-k3-am65-main-drop-dma-coherent-in-crypt.patch [new file with mode: 0644]
queue-5.10/arm64-dts-ti-k3-j721e-main-drop-dma-coherent-in-cryp.patch [new file with mode: 0644]
queue-5.10/arm64-make-is_ttbrx_addr-noinstr-safe.patch [new file with mode: 0644]
queue-5.10/asoc-codecs-rt298-add-quirk-for-kbl-r-rvp-platform.patch [new file with mode: 0644]
queue-5.10/asoc-dt-bindings-wcd9335-fix-reset-line-polarity-in-.patch [new file with mode: 0644]
queue-5.10/asoc-mediatek-mt8173-enable-irq-when-pdata-is-ready.patch [new file with mode: 0644]
queue-5.10/asoc-mediatek-mt8173-fix-debugfs-registration-for-co.patch [new file with mode: 0644]
queue-5.10/asoc-mediatek-mtk-btcvsd-add-checks-for-write-and-re.patch [new file with mode: 0644]
queue-5.10/asoc-pcm512x-fix-pm-disable-depth-imbalance-in-pcm51.patch [new file with mode: 0644]
queue-5.10/asoc-pxa-fix-null-pointer-dereference-in-filter.patch [new file with mode: 0644]
queue-5.10/asoc-qcom-add-checks-for-devm_kcalloc.patch [new file with mode: 0644]
queue-5.10/binfmt_misc-fix-shift-out-of-bounds-in-check_special.patch [new file with mode: 0644]
queue-5.10/blk-mq-fix-possible-memleak-when-register-hctx-faile.patch [new file with mode: 0644]
queue-5.10/blktrace-fix-output-non-blktrace-event-when-blk_clas.patch [new file with mode: 0644]
queue-5.10/bluetooth-btusb-don-t-call-kfree_skb-under-spin_lock.patch [new file with mode: 0644]
queue-5.10/bluetooth-hci_bcsp-don-t-call-kfree_skb-under-spin_l.patch [new file with mode: 0644]
queue-5.10/bluetooth-hci_core-don-t-call-kfree_skb-under-spin_l.patch [new file with mode: 0644]
queue-5.10/bluetooth-hci_h5-don-t-call-kfree_skb-under-spin_loc.patch [new file with mode: 0644]
queue-5.10/bluetooth-hci_ll-don-t-call-kfree_skb-under-spin_loc.patch [new file with mode: 0644]
queue-5.10/bluetooth-hci_qca-don-t-call-kfree_skb-under-spin_lo.patch [new file with mode: 0644]
queue-5.10/bluetooth-rfcomm-don-t-call-kfree_skb-under-spin_loc.patch [new file with mode: 0644]
queue-5.10/bonding-fix-link-recovery-in-mode-2-when-updelay-is-.patch [new file with mode: 0644]
queue-5.10/bonding-uninitialized-variable-in-bond_miimon_inspec.patch [new file with mode: 0644]
queue-5.10/bpf-check-the-other-end-of-slot_type-for-stack_spill.patch [new file with mode: 0644]
queue-5.10/bpf-fix-slot-type-check-in-check_stack_write_var_off.patch [new file with mode: 0644]
queue-5.10/bpf-make-sure-skb-len-0-when-redirecting-to-a-tunnel.patch [new file with mode: 0644]
queue-5.10/bpf-move-skb-len-0-checks-into-__bpf_redirect.patch [new file with mode: 0644]
queue-5.10/bpf-prevent-decl_tag-from-being-referenced-in-func_p.patch [new file with mode: 0644]
queue-5.10/bpf-propagate-precision-across-all-frames-not-just-t.patch [new file with mode: 0644]
queue-5.10/bpf-propagate-precision-in-alu-alu64-operations.patch [new file with mode: 0644]
queue-5.10/bpf-sockmap-fix-data-loss-caused-by-using-apply_byte.patch [new file with mode: 0644]
queue-5.10/bpf-sockmap-fix-race-in-sock_map_free.patch [new file with mode: 0644]
queue-5.10/bpf-sockmap-fix-repeated-calls-to-sock_put-when-msg-.patch [new file with mode: 0644]
queue-5.10/brcmfmac-return-error-when-getting-invalid-max_flowr.patch [new file with mode: 0644]
queue-5.10/can-kvaser_usb-add-struct-kvaser_usb_busparams.patch [new file with mode: 0644]
queue-5.10/can-kvaser_usb-compare-requested-bittiming-parameter.patch [new file with mode: 0644]
queue-5.10/can-kvaser_usb-do-not-increase-tx-statistics-when-se.patch [new file with mode: 0644]
queue-5.10/can-kvaser_usb-kvaser_usb_leaf-get-capabilities-from.patch [new file with mode: 0644]
queue-5.10/can-kvaser_usb-kvaser_usb_leaf-handle-cmd_error_even.patch [new file with mode: 0644]
queue-5.10/can-kvaser_usb-kvaser_usb_leaf-rename-leaf-usbcan-_c.patch [new file with mode: 0644]
queue-5.10/can-kvaser_usb_leaf-fix-bogus-restart-events.patch [new file with mode: 0644]
queue-5.10/can-kvaser_usb_leaf-fix-improved-state-not-being-rep.patch [new file with mode: 0644]
queue-5.10/can-kvaser_usb_leaf-fix-wrong-can-state-after-stoppi.patch [new file with mode: 0644]
queue-5.10/can-kvaser_usb_leaf-set-warning-state-even-without-b.patch [new file with mode: 0644]
queue-5.10/can-tcan4x5x-remove-invalid-write-in-clear_interrupt.patch [new file with mode: 0644]
queue-5.10/chardev-fix-error-handling-in-cdev_device_add.patch [new file with mode: 0644]
queue-5.10/class-fix-possible-memory-leak-in-__class_register.patch [new file with mode: 0644]
queue-5.10/clk-imx-replace-osc_hdmi-with-dummy.patch [new file with mode: 0644]
queue-5.10/clk-qcom-clk-krait-fix-wrong-div2-functions.patch [new file with mode: 0644]
queue-5.10/clk-qcom-gcc-sm8250-use-retention-mode-for-usb-gdscs.patch [new file with mode: 0644]
queue-5.10/clk-renesas-r9a06g032-repair-grave-increment-error.patch [new file with mode: 0644]
queue-5.10/clk-rockchip-fix-memory-leak-in-rockchip_clk_registe.patch [new file with mode: 0644]
queue-5.10/clk-samsung-fix-memory-leak-in-_samsung_clk_register.patch [new file with mode: 0644]
queue-5.10/clk-socfpga-clk-pll-remove-unused-variable-rc.patch [new file with mode: 0644]
queue-5.10/clk-socfpga-fix-memory-leak-in-socfpga_gate_init.patch [new file with mode: 0644]
queue-5.10/clk-socfpga-use-clk_hw_register-for-a5-c5.patch [new file with mode: 0644]
queue-5.10/clk-st-fix-memory-leak-in-st_of_quadfs_setup.patch [new file with mode: 0644]
queue-5.10/clocksource-drivers-sh_cmt-access-registers-accordin.patch [new file with mode: 0644]
queue-5.10/clocksource-drivers-sh_cmt-make-sure-channel-clock-s.patch [new file with mode: 0644]
queue-5.10/clocksource-drivers-timer-ti-dm-fix-missing-clk_disa.patch [new file with mode: 0644]
queue-5.10/configfs-fix-possible-memory-leak-in-configfs_create.patch [new file with mode: 0644]
queue-5.10/counter-stm32-lptimer-cnt-fix-the-check-on-arr-and-c.patch [new file with mode: 0644]
queue-5.10/cpu-hotplug-make-target_store-a-nop-when-target-stat.patch [new file with mode: 0644]
queue-5.10/cpufreq-amd_freq_sensitivity-add-missing-pci_dev_put.patch [new file with mode: 0644]
queue-5.10/cpufreq-qcom-hw-fix-memory-leak-in-qcom_cpufreq_hw_r.patch [new file with mode: 0644]
queue-5.10/cpuidle-dt-return-the-correct-numbers-of-parsed-idle.patch [new file with mode: 0644]
queue-5.10/crypto-amlogic-remove-kcalloc-without-check.patch [new file with mode: 0644]
queue-5.10/crypto-ccree-make-cc_debugfs_global_fini-available-f.patch [new file with mode: 0644]
queue-5.10/crypto-ccree-remove-debugfs-when-platform_driver_reg.patch [new file with mode: 0644]
queue-5.10/crypto-cryptd-use-request-context-instead-of-stack-f.patch [new file with mode: 0644]
queue-5.10/crypto-hisilicon-qm-add-missing-pci_dev_put-in-q_num.patch [new file with mode: 0644]
queue-5.10/crypto-img-hash-fix-variable-dereferenced-before-che.patch [new file with mode: 0644]
queue-5.10/crypto-nitrox-avoid-double-free-on-error-path-in-nit.patch [new file with mode: 0644]
queue-5.10/crypto-omap-sham-use-pm_runtime_resume_and_get-in-om.patch [new file with mode: 0644]
queue-5.10/crypto-rockchip-add-fallback-for-ahash.patch [new file with mode: 0644]
queue-5.10/crypto-rockchip-add-fallback-for-cipher.patch [new file with mode: 0644]
queue-5.10/crypto-rockchip-better-handle-cipher-key.patch [new file with mode: 0644]
queue-5.10/crypto-rockchip-delete-unneeded-variable-initializat.patch [new file with mode: 0644]
queue-5.10/crypto-rockchip-do-not-do-custom-power-management.patch [new file with mode: 0644]
queue-5.10/crypto-rockchip-do-not-store-mode-globally.patch [new file with mode: 0644]
queue-5.10/crypto-rockchip-remove-non-aligned-handling.patch [new file with mode: 0644]
queue-5.10/crypto-rockchip-rework-by-using-crypto_engine.patch [new file with mode: 0644]
queue-5.10/crypto-sun8i-ss-use-dma_addr-instead-u32.patch [new file with mode: 0644]
queue-5.10/crypto-tcrypt-fix-multibuffer-skcipher-speed-test-me.patch [new file with mode: 0644]
queue-5.10/cxl-fix-possible-null-ptr-deref-in-cxl_guest_init_af.patch [new file with mode: 0644]
queue-5.10/cxl-fix-possible-null-ptr-deref-in-cxl_pci_init_afu-.patch [new file with mode: 0644]
queue-5.10/cxl-fix-refcount-leak-in-cxl_calc_capp_routing.patch [new file with mode: 0644]
queue-5.10/debugfs-fix-error-when-writing-negative-value-to-ato.patch [new file with mode: 0644]
queue-5.10/dmaengine-idxd-fix-crc_val-field-for-completion-reco.patch [new file with mode: 0644]
queue-5.10/docs-fault-injection-fix-non-working-usage-of-negati.patch [new file with mode: 0644]
queue-5.10/drbd-fix-an-invalid-memory-access-caused-by-incorrec.patch [new file with mode: 0644]
queue-5.10/drivers-dio-fix-possible-memory-leak-in-dio_init.patch [new file with mode: 0644]
queue-5.10/drivers-mcb-fix-resource-leak-in-mcb_probe.patch [new file with mode: 0644]
queue-5.10/drivers-md-md-bitmap-check-the-return-value-of-md_bi.patch [new file with mode: 0644]
queue-5.10/drivers-net-qlcnic-fix-potential-memory-leak-in-qlcn.patch [new file with mode: 0644]
queue-5.10/drivers-soc-ti-knav_qmss_queue-mark-knav_acc_firmwar.patch [new file with mode: 0644]
queue-5.10/drm-amd-display-fix-array-index-out-of-bound-error-i.patch [new file with mode: 0644]
queue-5.10/drm-amd-display-prevent-memory-leak.patch [new file with mode: 0644]
queue-5.10/drm-amd-pm-smu11-baco-is-supported-when-it-s-in-baco.patch [new file with mode: 0644]
queue-5.10/drm-amdgpu-fix-pci-device-refcount-leak-in-amdgpu_at.patch [new file with mode: 0644]
queue-5.10/drm-amdgpu-fix-pci-device-refcount-leak.patch [new file with mode: 0644]
queue-5.10/drm-amdgpu-fix-type-of-second-parameter-in-odn_edit_.patch [new file with mode: 0644]
queue-5.10/drm-amdgpu-fix-type-of-second-parameter-in-trans_msg.patch [new file with mode: 0644]
queue-5.10/drm-bridge-adv7533-remove-dynamic-lane-switching-fro.patch [new file with mode: 0644]
queue-5.10/drm-etnaviv-add-missing-quirks-for-gc300.patch [new file with mode: 0644]
queue-5.10/drm-fourcc-add-packed-10bit-yuv-4-2-0-format.patch [new file with mode: 0644]
queue-5.10/drm-fourcc-fix-vsub-hsub-for-q410-and-q401.patch [new file with mode: 0644]
queue-5.10/drm-fsl-dcu-fix-return-type-of-fsl_dcu_drm_connector.patch [new file with mode: 0644]
queue-5.10/drm-mediatek-modify-dpi-power-on-off-sequence.patch [new file with mode: 0644]
queue-5.10/drm-msm-hdmi-drop-unused-gpio-support.patch [new file with mode: 0644]
queue-5.10/drm-msm-hdmi-switch-to-drm_bridge_connector.patch [new file with mode: 0644]
queue-5.10/drm-msm-use-drm_mode_copy.patch [new file with mode: 0644]
queue-5.10/drm-panel-panel-sitronix-st7701-remove-panel-on-dsi-.patch [new file with mode: 0644]
queue-5.10/drm-radeon-add-the-missed-acpi_put_table-to-fix-memo.patch [new file with mode: 0644]
queue-5.10/drm-radeon-fix-pci-device-refcount-leak-in-radeon_at.patch [new file with mode: 0644]
queue-5.10/drm-rockchip-lvds-fix-pm-usage-counter-unbalance-in-.patch [new file with mode: 0644]
queue-5.10/drm-rockchip-use-drm_mode_copy.patch [new file with mode: 0644]
queue-5.10/drm-sti-fix-return-type-of-sti_-dvo-hda-hdmi-_connec.patch [new file with mode: 0644]
queue-5.10/drm-sti-use-drm_mode_copy.patch [new file with mode: 0644]
queue-5.10/drm-tegra-add-missing-clk_disable_unprepare-in-tegra.patch [new file with mode: 0644]
queue-5.10/edac-i10nm-fix-refcount-leak-in-pci_get_dev_wrapper.patch [new file with mode: 0644]
queue-5.10/ethernet-s2io-don-t-call-dev_kfree_skb-under-spin_lo.patch [new file with mode: 0644]
queue-5.10/ethtool-avoiding-integer-overflow-in-ethtool_phys_id.patch [new file with mode: 0644]
queue-5.10/eventfd-change-int-to-__u64-in-eventfd_signal-ifndef.patch [new file with mode: 0644]
queue-5.10/f2fs-avoid-victim-selection-from-previous-victim-sec.patch [new file with mode: 0644]
queue-5.10/f2fs-fix-normal-discard-process.patch [new file with mode: 0644]
queue-5.10/f2fs-fix-the-race-condition-of-resize-flag-between-r.patch [new file with mode: 0644]
queue-5.10/fbdev-pm2fb-fix-missing-pci_disable_device.patch [new file with mode: 0644]
queue-5.10/fbdev-ssd1307fb-drop-optional-dependency.patch [new file with mode: 0644]
queue-5.10/fbdev-uvesafb-fixes-an-error-handling-path-in-uvesaf.patch [new file with mode: 0644]
queue-5.10/fbdev-vermilion-decrease-reference-count-in-error-pa.patch [new file with mode: 0644]
queue-5.10/fbdev-via-fix-error-in-via_core_init.patch [new file with mode: 0644]
queue-5.10/firmware-raspberrypi-fix-possible-memory-leak-in-rpi.patch [new file with mode: 0644]
queue-5.10/fs-don-t-audit-the-capability-check-in-simple_xattr_.patch [new file with mode: 0644]
queue-5.10/fs-jfs-fix-shift-out-of-bounds-in-dballocag.patch [new file with mode: 0644]
queue-5.10/fs-jfs-fix-shift-out-of-bounds-in-dbdiscardag.patch [new file with mode: 0644]
queue-5.10/fs-sysv-fix-sysv_nblocks-returns-wrong-value.patch [new file with mode: 0644]
queue-5.10/futex-move-to-kernel-futex.patch [new file with mode: 0644]
queue-5.10/futex-resend-potentially-swallowed-owner-death-notif.patch [new file with mode: 0644]
queue-5.10/genirq-add-irqf_no_autoen-for-request_irq-nmi.patch [new file with mode: 0644]
queue-5.10/genirq-irqdesc-don-t-try-to-remove-non-existing-sysf.patch [new file with mode: 0644]
queue-5.10/gpiolib-cdev-fix-null-pointer-dereferences.patch [new file with mode: 0644]
queue-5.10/gpiolib-get-rid-of-redundant-else.patch [new file with mode: 0644]
queue-5.10/hamradio-baycom_epp-fix-return-type-of-baycom_send_p.patch [new file with mode: 0644]
queue-5.10/hamradio-don-t-call-dev_kfree_skb-under-spin_lock_ir.patch [new file with mode: 0644]
queue-5.10/hfs-fix-oob-read-in-__hfs_brec_find.patch [new file with mode: 0644]
queue-5.10/hfs-fix-oob-write-in-hfs_asc2mac.patch [new file with mode: 0644]
queue-5.10/hid-hid-sensor-custom-set-fixed-size-for-custom-attr.patch [new file with mode: 0644]
queue-5.10/hsi-omap_ssi_core-fix-error-handling-in-ssi_init.patch [new file with mode: 0644]
queue-5.10/hsi-omap_ssi_core-fix-possible-memory-leak-in-ssi_pr.patch [new file with mode: 0644]
queue-5.10/hsi-omap_ssi_core-fix-unbalanced-pm_runtime_disable.patch [new file with mode: 0644]
queue-5.10/hsr-add-a-rcu-read-lock-to-hsr_forward_skb.patch [new file with mode: 0644]
queue-5.10/hsr-disable-netpoll.patch [new file with mode: 0644]
queue-5.10/hsr-synchronize-sending-frames-to-have-always-increm.patch [new file with mode: 0644]
queue-5.10/hsr-synchronize-sequence-number-updates.patch [new file with mode: 0644]
queue-5.10/hugetlbfs-fix-null-ptr-deref-in-hugetlbfs_parse_para.patch [new file with mode: 0644]
queue-5.10/hwmon-jc42-convert-register-access-and-caching-to-re.patch [new file with mode: 0644]
queue-5.10/hwmon-jc42-restore-the-min-max-critical-temperatures.patch [new file with mode: 0644]
queue-5.10/hwrng-amd-fix-pci-device-refcount-leak.patch [new file with mode: 0644]
queue-5.10/hwrng-geode-fix-pci-device-refcount-leak.patch [new file with mode: 0644]
queue-5.10/i2c-ismt-fix-an-out-of-bounds-bug-in-ismt_access.patch [new file with mode: 0644]
queue-5.10/i2c-mux-reg-check-return-value-after-calling-platfor.patch [new file with mode: 0644]
queue-5.10/i2c-pxa-pci-fix-missing-pci_disable_device-on-error-.patch [new file with mode: 0644]
queue-5.10/ib-ipoib-fix-queue-count-inconsistency-for-pkey-chil.patch [new file with mode: 0644]
queue-5.10/igb-do-not-free-q_vector-unless-new-one-was-allocate.patch [new file with mode: 0644]
queue-5.10/igc-add-checking-for-basetime-less-than-zero.patch [new file with mode: 0644]
queue-5.10/igc-enhance-qbv-scheduling-by-using-first-flag-bit.patch [new file with mode: 0644]
queue-5.10/igc-lift-taprio-schedule-restriction.patch [new file with mode: 0644]
queue-5.10/igc-recalculate-qbv-end_time-by-considering-cycle-ti.patch [new file with mode: 0644]
queue-5.10/igc-set-qbv-start_time-and-end_time-to-end_time-if-n.patch [new file with mode: 0644]
queue-5.10/igc-use-strict-cycles-for-qbv-scheduling.patch [new file with mode: 0644]
queue-5.10/iio-adis-add-__adis_enable_irq-implementation.patch [new file with mode: 0644]
queue-5.10/iio-adis-handle-devices-that-cannot-unmask-the-drdy-.patch [new file with mode: 0644]
queue-5.10/iio-adis-stylistic-changes.patch [new file with mode: 0644]
queue-5.10/iio-imu-adis-move-exports-into-iio_adislib-namespace.patch [new file with mode: 0644]
queue-5.10/iio-imu-adis-use-irqf_no_autoen-instead-of-irq-reque.patch [new file with mode: 0644]
queue-5.10/iio-temperature-ltc2983-make-bulk-write-buffer-dma-s.patch [new file with mode: 0644]
queue-5.10/ima-fix-fall-through-warnings-for-clang.patch [new file with mode: 0644]
queue-5.10/ima-fix-misuse-of-dereference-of-pointer-in-template.patch [new file with mode: 0644]
queue-5.10/ima-handle-estale-returned-by-ima_filter_rule_match.patch [new file with mode: 0644]
queue-5.10/include-uapi-linux-swab-fix-potentially-missing-__al.patch [new file with mode: 0644]
queue-5.10/inet-add-read_once-sk-sk_bound_dev_if-in-inet_csk_bi.patch [new file with mode: 0644]
queue-5.10/input-elants_i2c-properly-handle-the-reset-gpio-when.patch [new file with mode: 0644]
queue-5.10/input-joystick-fix-kconfig-warning-for-joystick_adc.patch [new file with mode: 0644]
queue-5.10/integrity-fix-memory-leakage-in-keyring-allocation-e.patch [new file with mode: 0644]
queue-5.10/iommu-amd-fix-pci-device-refcount-leak-in-ppr_notifi.patch [new file with mode: 0644]
queue-5.10/iommu-fsl_pamu-fix-resource-leak-in-fsl_pamu_probe.patch [new file with mode: 0644]
queue-5.10/iommu-sun50i-consider-all-fault-sources-for-reset.patch [new file with mode: 0644]
queue-5.10/iommu-sun50i-fix-flush-size.patch [new file with mode: 0644]
queue-5.10/iommu-sun50i-fix-r-w-permission-check.patch [new file with mode: 0644]
queue-5.10/iommu-sun50i-fix-reset-release.patch [new file with mode: 0644]
queue-5.10/iommu-sun50i-remove-iommu_domain_identity.patch [new file with mode: 0644]
queue-5.10/ipmi-fix-memleak-when-unload-ipmi-driver.patch [new file with mode: 0644]
queue-5.10/irqchip-gic-pm-use-pm_runtime_resume_and_get-in-gic_.patch [new file with mode: 0644]
queue-5.10/kbuild-refactor-single-builds-of-.ko.patch [new file with mode: 0644]
queue-5.10/kbuild-remove-unneeded-mkdir-for-external-modules_in.patch [new file with mode: 0644]
queue-5.10/kbuild-unify-modules-_install-for-in-tree-and-extern.patch [new file with mode: 0644]
queue-5.10/lib-debugobjects-fix-stat-count-and-optimize-debug_o.patch [new file with mode: 0644]
queue-5.10/lib-fonts-fix-undefined-behavior-in-bit-shift-for-ge.patch [new file with mode: 0644]
queue-5.10/lib-notifier-error-inject-fix-error-when-writing-err.patch [new file with mode: 0644]
queue-5.10/libbpf-avoid-enum-forward-declarations-in-public-api.patch [new file with mode: 0644]
queue-5.10/libbpf-fix-null-pointer-dereference-in-find_prog_by_.patch [new file with mode: 0644]
queue-5.10/libbpf-fix-use-after-free-in-btf_dump_name_dups.patch [new file with mode: 0644]
queue-5.10/libfs-add-define_simple_attribute_signed-for-signed-.patch [new file with mode: 0644]
queue-5.10/macintosh-fix-possible-memory-leak-in-macio_add_one_.patch [new file with mode: 0644]
queue-5.10/macintosh-macio-adb-check-the-return-value-of-iorema.patch [new file with mode: 0644]
queue-5.10/mailbox-zynq-ipi-fix-error-handling-while-device_reg.patch [new file with mode: 0644]
queue-5.10/mcb-mcb-parse-fix-error-handing-in-chameleon_parse_g.patch [new file with mode: 0644]
queue-5.10/md-raid1-stop-mdx_raid1-thread-when-raid1-array-run-.patch [new file with mode: 0644]
queue-5.10/media-c8sectpfe-add-of_node_put-when-breaking-out-of.patch [new file with mode: 0644]
queue-5.10/media-camss-clean-up-received-buffers-on-failed-star.patch [new file with mode: 0644]
queue-5.10/media-coda-add-check-for-dcoda_iram_alloc.patch [new file with mode: 0644]
queue-5.10/media-coda-add-check-for-kmalloc.patch [new file with mode: 0644]
queue-5.10/media-coda-jpeg-add-check-for-kmalloc.patch [new file with mode: 0644]
queue-5.10/media-dvb-core-fix-ignored-return-value-in-dvb_regis.patch [new file with mode: 0644]
queue-5.10/media-dvb-frontends-fix-leak-of-memory-fw.patch [new file with mode: 0644]
queue-5.10/media-dvb-usb-az6027-fix-null-ptr-deref-in-az6027_i2.patch [new file with mode: 0644]
queue-5.10/media-dvb-usb-fix-memory-leak-in-dvb_usb_adapter_ini.patch [new file with mode: 0644]
queue-5.10/media-dvbdev-adopts-refcnt-to-avoid-uaf.patch [new file with mode: 0644]
queue-5.10/media-exynos4-is-don-t-rely-on-the-v4l2_async_subdev.patch [new file with mode: 0644]
queue-5.10/media-exynos4-is-use-v4l2_async_notifier_add_fwnode_.patch [new file with mode: 0644]
queue-5.10/media-i2c-ad5820-fix-error-path.patch [new file with mode: 0644]
queue-5.10/media-imon-fix-a-race-condition-in-send_packet.patch [new file with mode: 0644]
queue-5.10/media-platform-exynos4-is-fix-error-handling-in-fimc.patch [new file with mode: 0644]
queue-5.10/media-platform-exynos4-is-fix-return-value-check-in-.patch [new file with mode: 0644]
queue-5.10/media-s5p-mfc-add-variant-data-for-mfc-v7-hardware-f.patch [new file with mode: 0644]
queue-5.10/media-saa7164-fix-missing-pci_disable_device.patch [new file with mode: 0644]
queue-5.10/media-si470x-fix-use-after-free-in-si470x_int_in_cal.patch [new file with mode: 0644]
queue-5.10/media-solo6x10-fix-possible-memory-leak-in-solo_sysf.patch [new file with mode: 0644]
queue-5.10/media-videobuf-dma-contig-use-dma_mmap_coherent.patch [new file with mode: 0644]
queue-5.10/media-vidtv-fix-use-after-free-in-vidtv_bridge_dvb_i.patch [new file with mode: 0644]
queue-5.10/media-vimc-fix-wrong-function-called-when-vimc_init-.patch [new file with mode: 0644]
queue-5.10/media-vivid-fix-compose-size-exceed-boundary.patch [new file with mode: 0644]
queue-5.10/mfd-qcom_rpm-fix-an-error-handling-path-in-qcom_rpm_.patch [new file with mode: 0644]
queue-5.10/mips-bcm63xx-add-check-for-null-for-clk-in-clk_enabl.patch [new file with mode: 0644]
queue-5.10/mips-octeon-warn-only-once-if-deprecated-link-status.patch [new file with mode: 0644]
queue-5.10/mips-vpe-cmp-fix-possible-memory-leak-while-module-e.patch [new file with mode: 0644]
queue-5.10/mips-vpe-mt-fix-possible-memory-leak-while-module-ex.patch [new file with mode: 0644]
queue-5.10/misc-ocxl-fix-possible-name-leak-in-ocxl_file_regist.patch [new file with mode: 0644]
queue-5.10/misc-sgi-gru-fix-use-after-free-error-in-gru_set_con.patch [new file with mode: 0644]
queue-5.10/misc-tifm-fix-possible-memory-leak-in-tifm_7xx1_swit.patch [new file with mode: 0644]
queue-5.10/misdn-hfcmulti-don-t-call-dev_kfree_skb-kfree_skb-un.patch [new file with mode: 0644]
queue-5.10/misdn-hfcpci-don-t-call-dev_kfree_skb-kfree_skb-unde.patch [new file with mode: 0644]
queue-5.10/misdn-hfcsusb-don-t-call-dev_kfree_skb-kfree_skb-und.patch [new file with mode: 0644]
queue-5.10/mmc-alcor-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mmc-atmel-mci-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mmc-f-sdh30-add-quirks-for-broken-timeout-clock-capa.patch [new file with mode: 0644]
queue-5.10/mmc-meson-gx-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mmc-mmci-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mmc-moxart-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mmc-mxcmmc-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mmc-omap_hsmmc-fix-return-value-check-of-mmc_add_hos.patch [new file with mode: 0644]
queue-5.10/mmc-pxamci-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mmc-renesas_sdhi-better-reset-from-hs400-mode.patch [new file with mode: 0644]
queue-5.10/mmc-rtsx_usb_sdmmc-fix-return-value-check-of-mmc_add.patch [new file with mode: 0644]
queue-5.10/mmc-toshsd-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mmc-via-sdmmc-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mmc-vub300-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mmc-wbsd-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mmc-wmt-sdmmc-fix-return-value-check-of-mmc_add_host.patch [new file with mode: 0644]
queue-5.10/mrp-introduce-active-flags-to-prevent-uaf-when-appli.patch [new file with mode: 0644]
queue-5.10/mtd-fix-device-name-leak-when-register-device-failed.patch [new file with mode: 0644]
queue-5.10/mtd-lpddr2_nvm-fix-possible-null-ptr-deref.patch [new file with mode: 0644]
queue-5.10/mtd-maps-pxa2xx-flash-fix-memory-leak-in-probe.patch [new file with mode: 0644]
queue-5.10/myri10ge-fix-an-error-handling-path-in-myri10ge_prob.patch [new file with mode: 0644]
queue-5.10/net-add-a-helper-to-avoid-issues-with-hw-tx-timestam.patch [new file with mode: 0644]
queue-5.10/net-add-atomic_long_t-to-net_device_stats-fields.patch [new file with mode: 0644]
queue-5.10/net-add-inline-function-skb_csum_is_sctp.patch [new file with mode: 0644]
queue-5.10/net-amd-lance-don-t-call-dev_kfree_skb-under-spin_lo.patch [new file with mode: 0644]
queue-5.10/net-amd-xgbe-check-only-the-minimum-speed-for-active.patch [new file with mode: 0644]
queue-5.10/net-amd-xgbe-fix-logic-around-active-and-passive-cab.patch [new file with mode: 0644]
queue-5.10/net-apple-bmac-don-t-call-dev_kfree_skb-under-spin_l.patch [new file with mode: 0644]
queue-5.10/net-apple-mace-don-t-call-dev_kfree_skb-under-spin_l.patch [new file with mode: 0644]
queue-5.10/net-defxx-fix-missing-err-handling-in-dfx_init.patch [new file with mode: 0644]
queue-5.10/net-emaclite-don-t-call-dev_kfree_skb-under-spin_loc.patch [new file with mode: 0644]
queue-5.10/net-ethernet-dnet-don-t-call-dev_kfree_skb-under-spi.patch [new file with mode: 0644]
queue-5.10/net-ethernet-ti-fix-return-type-of-netcp_ndo_start_x.patch [new file with mode: 0644]
queue-5.10/net-farsync-fix-kmemleak-when-rmmods-farsync.patch [new file with mode: 0644]
queue-5.10/net-hsr-generate-supervision-frame-without-hsr-prp-t.patch [new file with mode: 0644]
queue-5.10/net-igc-use-skb_csum_is_sctp-instead-of-protocol-che.patch [new file with mode: 0644]
queue-5.10/net-lan9303-fix-read-error-execution-path.patch [new file with mode: 0644]
queue-5.10/net-macsec-fix-net-device-access-prior-to-holding-a-.patch [new file with mode: 0644]
queue-5.10/net-proc-provide-proc_fs-n-fallback-for-proc_create_.patch [new file with mode: 0644]
queue-5.10/net-stmmac-selftests-fix-potential-memleak-in-stmmac.patch [new file with mode: 0644]
queue-5.10/net-stream-purge-sk_error_queue-in-sk_stream_kill_qu.patch [new file with mode: 0644]
queue-5.10/net-switch-to-storing-kcov-handle-directly-in-sk_buf.patch [new file with mode: 0644]
queue-5.10/net-tunnel-wait-until-all-sk_user_data-reader-finish.patch [new file with mode: 0644]
queue-5.10/net-vmw_vsock-vmci-check-memcpy_from_msg.patch [new file with mode: 0644]
queue-5.10/net_sched-reject-tcf_em_simple-case-for-complex-emat.patch [new file with mode: 0644]
queue-5.10/netfilter-conntrack-set-icmpv6-redirects-as-related.patch [new file with mode: 0644]
queue-5.10/netfilter-flowtable-really-fix-nat-ipv6-offload.patch [new file with mode: 0644]
queue-5.10/nfc-pn533-clear-nfc_target-before-being-used.patch [new file with mode: 0644]
queue-5.10/nfs-fix-an-oops-in-nfs_d_automount.patch [new file with mode: 0644]
queue-5.10/nfsd-don-t-call-nfsd_file_put-from-client-states-seq.patch [new file with mode: 0644]
queue-5.10/nfsd-remove-spurious-cb_setup_err-tracepoint.patch [new file with mode: 0644]
queue-5.10/nfsd-under-nfsv4.1-fix-double-svc_xprt_put-on-rpc_cr.patch [new file with mode: 0644]
queue-5.10/nfsv4-fix-a-deadlock-between-nfs4_open_recover_helpe.patch [new file with mode: 0644]
queue-5.10/nfsv4.2-clear-fattr4_word2_security_label-when-done-.patch [new file with mode: 0644]
queue-5.10/nfsv4.2-fix-a-memory-stomp-in-decode_attr_security_l.patch [new file with mode: 0644]
queue-5.10/nfsv4.2-fix-initialisation-of-struct-nfs4_label.patch [new file with mode: 0644]
queue-5.10/nfsv4.x-fail-client-initialisation-if-state-manager-.patch [new file with mode: 0644]
queue-5.10/nilfs2-fix-shift-out-of-bounds-due-to-too-large-expo.patch [new file with mode: 0644]
queue-5.10/nilfs2-fix-shift-out-of-bounds-overflow-in-nilfs_sb2.patch [new file with mode: 0644]
queue-5.10/ntb_netdev-use-dev_kfree_skb_any-in-interrupt-contex.patch [new file with mode: 0644]
queue-5.10/objtool-kcsan-add-volatile-read-write-instrumentatio.patch [new file with mode: 0644]
queue-5.10/ocfs2-fix-memory-leak-in-ocfs2_mount_volume.patch [new file with mode: 0644]
queue-5.10/ocfs2-fix-memory-leak-in-ocfs2_stack_glue_init.patch [new file with mode: 0644]
queue-5.10/ocfs2-ocfs2_mount_volume-does-cleanup-job-before-ret.patch [new file with mode: 0644]
queue-5.10/ocfs2-rewrite-error-handling-of-ocfs2_fill_super.patch [new file with mode: 0644]
queue-5.10/ocxl-fix-pci-device-refcount-leak-when-calling-get_f.patch [new file with mode: 0644]
queue-5.10/of-overlay-fix-null-pointer-dereferencing-in-find_du.patch [new file with mode: 0644]
queue-5.10/openvswitch-fix-flow-lookup-to-use-unmasked-key.patch [new file with mode: 0644]
queue-5.10/orangefs-fix-kmemleak-in-orangefs_-kernel-client-_de.patch [new file with mode: 0644]
queue-5.10/orangefs-fix-kmemleak-in-orangefs_prepare_debugfs_he.patch [new file with mode: 0644]
queue-5.10/orangefs-fix-sysfs-not-cleanup-when-dev-init-failed.patch [new file with mode: 0644]
queue-5.10/padata-always-leave-bhs-disabled-when-running-parall.patch [new file with mode: 0644]
queue-5.10/padata-fix-list-iterator-in-padata_do_serial.patch [new file with mode: 0644]
queue-5.10/pata_ipx4xx_cf-fix-unsigned-comparison-with-less-tha.patch [new file with mode: 0644]
queue-5.10/pci-check-for-alloc-failure-in-pci_request_irq.patch [new file with mode: 0644]
queue-5.10/pci-dwc-fix-n_fts-array-overrun.patch [new file with mode: 0644]
queue-5.10/pci-pci-epf-test-register-notifier-if-only-core_init.patch [new file with mode: 0644]
queue-5.10/perf-arm_dsu-fix-hotplug-callback-leak-in-dsu_pmu_in.patch [new file with mode: 0644]
queue-5.10/perf-fix-possible-memleak-in-pmu_dev_alloc.patch [new file with mode: 0644]
queue-5.10/perf-smmuv3-fix-hotplug-callback-leak-in-arm_smmu_pm.patch [new file with mode: 0644]
queue-5.10/perf-symbol-correction-while-adjusting-symbol.patch [new file with mode: 0644]
queue-5.10/perf-trace-handle-failure-when-trace-point-folder-is.patch [new file with mode: 0644]
queue-5.10/perf-trace-return-error-if-a-system-call-doesn-t-exi.patch [new file with mode: 0644]
queue-5.10/perf-trace-use-macro-raw_syscall_args_num-to-replace.patch [new file with mode: 0644]
queue-5.10/perf-x86-intel-uncore-fix-reference-count-leak-in-__.patch [new file with mode: 0644]
queue-5.10/perf-x86-intel-uncore-fix-reference-count-leak-in-hs.patch [new file with mode: 0644]
queue-5.10/perf-x86-intel-uncore-fix-reference-count-leak-in-sn.patch [new file with mode: 0644]
queue-5.10/phy-qcom-qmp-combo-fix-runtime-suspend.patch [new file with mode: 0644]
queue-5.10/phy-qcom-qmp-create-copies-of-qmp-phy-driver.patch [new file with mode: 0644]
queue-5.10/phy-usb-s2-wol-wakeup_count-not-incremented-for-usb-.patch [new file with mode: 0644]
queue-5.10/pinctrl-pinconf-generic-add-missing-of_node_put.patch [new file with mode: 0644]
queue-5.10/platform-chrome-cros_usbpd_notify-fix-error-handling.patch [new file with mode: 0644]
queue-5.10/platform-x86-huawei-wmi-fix-return-value-calculation.patch [new file with mode: 0644]
queue-5.10/platform-x86-intel_scu_ipc-fix-possible-name-leak-in.patch [new file with mode: 0644]
queue-5.10/platform-x86-mxm-wmi-fix-memleak-in-mxm_wmi_call_mx-.patch [new file with mode: 0644]
queue-5.10/pm-hibernate-fix-mistake-in-kerneldoc-comment.patch [new file with mode: 0644]
queue-5.10/pm-runtime-do-not-call-__rpm_callback-from-rpm_idle.patch [new file with mode: 0644]
queue-5.10/pm-runtime-improve-path-in-rpm_idle-when-no-callback.patch [new file with mode: 0644]
queue-5.10/pnp-fix-name-memory-leak-in-pnp_alloc_dev.patch [new file with mode: 0644]
queue-5.10/power-supply-fix-null-pointer-dereferencing-in-power.patch [new file with mode: 0644]
queue-5.10/power-supply-fix-residue-sysfs-file-in-error-handle-.patch [new file with mode: 0644]
queue-5.10/powerpc-52xx-fix-a-resource-leak-in-an-error-handlin.patch [new file with mode: 0644]
queue-5.10/powerpc-83xx-mpc832x_rdb-call-platform_device_put-in.patch [new file with mode: 0644]
queue-5.10/powerpc-dts-t208x-mark-mac1-and-mac2-as-10g.patch [new file with mode: 0644]
queue-5.10/powerpc-eeh-drop-redundant-spinlock-initialization.patch [new file with mode: 0644]
queue-5.10/powerpc-hv-gpci-fix-hv_gpci-event-list.patch [new file with mode: 0644]
queue-5.10/powerpc-perf-callchain-validate-kernel-stack-pointer.patch [new file with mode: 0644]
queue-5.10/powerpc-pseries-eeh-use-correct-api-for-error-log-si.patch [new file with mode: 0644]
queue-5.10/powerpc-xive-add-missing-iounmap-in-error-path-in-xi.patch [new file with mode: 0644]
queue-5.10/powerpc-xmon-enable-breakpoints-on-8xx.patch [new file with mode: 0644]
queue-5.10/powerpc-xmon-fix-wswitch-unreachable-warning-in-bpt_.patch [new file with mode: 0644]
queue-5.10/ppp-associate-skb-with-a-device-at-tx.patch [new file with mode: 0644]
queue-5.10/proc-fixup-uptime-selftest.patch [new file with mode: 0644]
queue-5.10/pstore-avoid-kcore-oops-by-vmap-ing-with-vm_ioremap.patch [new file with mode: 0644]
queue-5.10/pstore-ram-fix-error-return-code-in-ramoops_probe.patch [new file with mode: 0644]
queue-5.10/pwm-sifive-call-pwm_sifive_update_clock-while-mutex-.patch [new file with mode: 0644]
queue-5.10/pwm-tegra-improve-required-rate-calculation.patch [new file with mode: 0644]
queue-5.10/qed-gcc13-use-u16-for-fid-to-be-big-enough.patch [new file with mode: 0644]
queue-5.10/r6040-fix-kmemleak-in-probe-and-remove.patch [new file with mode: 0644]
queue-5.10/rapidio-devices-fix-missing-put_device-in-mport_cdev.patch [new file with mode: 0644]
queue-5.10/rapidio-fix-possible-name-leaks-when-rio_add_device-.patch [new file with mode: 0644]
queue-5.10/rapidio-fix-possible-uaf-when-kfifo_alloc-fails.patch [new file with mode: 0644]
queue-5.10/rapidio-rio-fix-possible-name-leak-in-rio_register_m.patch [new file with mode: 0644]
queue-5.10/rcu-fix-__this_cpu_read-lockdep-warning-in-rcu_force.patch [new file with mode: 0644]
queue-5.10/rdma-core-fix-order-of-nldev_exit-call.patch [new file with mode: 0644]
queue-5.10/rdma-hfi-decrease-pci-device-reference-count-in-erro.patch [new file with mode: 0644]
queue-5.10/rdma-hfi1-fix-error-return-code-in-parse_platform_co.patch [new file with mode: 0644]
queue-5.10/rdma-hns-fix-ext_sge-num-error-when-post-send.patch [new file with mode: 0644]
queue-5.10/rdma-hns-fix-memory-leak-in-hns_roce_alloc_mr.patch [new file with mode: 0644]
queue-5.10/rdma-hns-fix-page-size-cap-from-firmware.patch [new file with mode: 0644]
queue-5.10/rdma-hns-fix-pbl-page-mtr-find.patch [new file with mode: 0644]
queue-5.10/rdma-hns-repacing-dseg_len-by-macros-in-fill_ext_sge.patch [new file with mode: 0644]
queue-5.10/rdma-nldev-add-checks-for-nla_nest_start-in-fill_sta.patch [new file with mode: 0644]
queue-5.10/rdma-nldev-fix-failure-to-send-large-messages.patch [new file with mode: 0644]
queue-5.10/rdma-nldev-return-eagain-if-the-cm_id-isn-t-from-exp.patch [new file with mode: 0644]
queue-5.10/rdma-rxe-fix-null-ptr-deref-in-rxe_qp_do_cleanup-whe.patch [new file with mode: 0644]
queue-5.10/rdma-siw-fix-immediate-work-request-flush-to-complet.patch [new file with mode: 0644]
queue-5.10/rdma-siw-fix-pointer-cast-warning.patch [new file with mode: 0644]
queue-5.10/rdma-siw-set-defined-status-for-work-completion-with.patch [new file with mode: 0644]
queue-5.10/rdma-srp-fix-error-return-code-in-srp_parse_options.patch [new file with mode: 0644]
queue-5.10/regulator-core-fix-module-refcount-leak-in-set_suppl.patch [new file with mode: 0644]
queue-5.10/regulator-core-fix-resource-leak-in-regulator_regist.patch [new file with mode: 0644]
queue-5.10/regulator-core-fix-unbalanced-of-node-refcount-in-re.patch [new file with mode: 0644]
queue-5.10/regulator-core-fix-use_count-leakage-when-handling-b.patch [new file with mode: 0644]
queue-5.10/regulator-core-use-kfree_const-to-free-space-conditi.patch [new file with mode: 0644]
queue-5.10/relay-fix-type-mismatch-when-allocating-memory-in-re.patch [new file with mode: 0644]
queue-5.10/remoteproc-qcom_q6v5_pas-detach-power-domains-on-rem.patch [new file with mode: 0644]
queue-5.10/remoteproc-qcom_q6v5_pas-disable-wakeup-on-probe-fai.patch [new file with mode: 0644]
queue-5.10/remoteproc-qcom_q6v5_pas-fix-missing-of_node_put-in-.patch [new file with mode: 0644]
queue-5.10/remoteproc-sysmon-fix-memory-leak-in-qcom_add_sysmon.patch [new file with mode: 0644]
queue-5.10/riscv-mm-add-arch-hook-arch_clear_hugepage_flags.patch [new file with mode: 0644]
queue-5.10/rtc-cmos-call-cmos_wake_setup-from-cmos_do_probe.patch [new file with mode: 0644]
queue-5.10/rtc-cmos-call-rtc_wake_setup-from-cmos_do_probe.patch [new file with mode: 0644]
queue-5.10/rtc-cmos-disable-acpi-rtc-event-on-removal.patch [new file with mode: 0644]
queue-5.10/rtc-cmos-eliminate-forward-declarations-of-some-func.patch [new file with mode: 0644]
queue-5.10/rtc-cmos-fix-build-on-non-acpi-platforms.patch [new file with mode: 0644]
queue-5.10/rtc-cmos-fix-event-handler-registration-ordering-iss.patch [new file with mode: 0644]
queue-5.10/rtc-cmos-fix-wake-alarm-breakage.patch [new file with mode: 0644]
queue-5.10/rtc-cmos-rename-acpi-related-functions.patch [new file with mode: 0644]
queue-5.10/rtc-mxc_v2-add-missing-clk_disable_unprepare.patch [new file with mode: 0644]
queue-5.10/rtc-pcf85063-fix-pcf85063_clkout_control.patch [new file with mode: 0644]
queue-5.10/rtc-pcf85063-fix-reading-alarm.patch [new file with mode: 0644]
queue-5.10/rtc-pic32-move-devm_rtc_allocate_device-earlier-in-p.patch [new file with mode: 0644]
queue-5.10/rtc-rtc-cmos-do-not-check-acpi_fadt_low_power_s0.patch [new file with mode: 0644]
queue-5.10/rtc-snvs-allow-a-time-difference-on-clock-register-r.patch [new file with mode: 0644]
queue-5.10/rtc-st-lpc-add-missing-clk_disable_unprepare-in-st_r.patch [new file with mode: 0644]
queue-5.10/rxrpc-fix-ack.buffersize-to-be-0-when-generating-an-.patch [new file with mode: 0644]
queue-5.10/rxrpc-fix-missing-unlock-in-rxrpc_do_sendmsg.patch [new file with mode: 0644]
queue-5.10/s390-ctcm-fix-return-type-of-ctc-mp-m_tx.patch [new file with mode: 0644]
queue-5.10/s390-lcs-fix-return-type-of-lcs_start_xmit.patch [new file with mode: 0644]
queue-5.10/s390-netiucv-fix-return-type-of-netiucv_tx.patch [new file with mode: 0644]
queue-5.10/samples-vfio-mdev-fix-missing-pci_disable_device-in-.patch [new file with mode: 0644]
queue-5.10/sched-fair-cleanup-task_util-and-capacity-type.patch [new file with mode: 0644]
queue-5.10/sched-uclamp-fix-relationship-between-uclamp-and-mig.patch [new file with mode: 0644]
queue-5.10/scsi-core-fix-a-race-between-scsi_done-and-scsi_time.patch [new file with mode: 0644]
queue-5.10/scsi-fcoe-fix-possible-name-leak-when-device_registe.patch [new file with mode: 0644]
queue-5.10/scsi-fcoe-fix-transport-not-deattached-when-fcoe_if_.patch [new file with mode: 0644]
queue-5.10/scsi-hpsa-fix-error-handling-in-hpsa_add_sas_host.patch [new file with mode: 0644]
queue-5.10/scsi-hpsa-fix-possible-memory-leak-in-hpsa_add_sas_d.patch [new file with mode: 0644]
queue-5.10/scsi-hpsa-fix-possible-memory-leak-in-hpsa_init_one.patch [new file with mode: 0644]
queue-5.10/scsi-ipr-fix-warning-in-ipr_init.patch [new file with mode: 0644]
queue-5.10/scsi-mpt3sas-fix-possible-resource-leaks-in-mpt3sas_.patch [new file with mode: 0644]
queue-5.10/scsi-scsi_debug-fix-a-warning-in-resp_report_zones.patch [new file with mode: 0644]
queue-5.10/scsi-scsi_debug-fix-a-warning-in-resp_verify.patch [new file with mode: 0644]
queue-5.10/scsi-scsi_debug-fix-a-warning-in-resp_write_scat.patch [new file with mode: 0644]
queue-5.10/scsi-scsi_debug-fix-possible-name-leak-in-sdebug_add.patch [new file with mode: 0644]
queue-5.10/scsi-snic-fix-possible-uaf-in-snic_tgt_create.patch [new file with mode: 0644]
queue-5.10/sctp-sysctl-make-extra-pointers-netns-aware.patch [new file with mode: 0644]
queue-5.10/selftests-devlink-fix-the-fd-redirect-in-dummy_repor.patch [new file with mode: 0644]
queue-5.10/selftests-efivarfs-add-checking-of-the-test-return-v.patch [new file with mode: 0644]
queue-5.10/selftests-ftrace-event_triggers-wait-longer-for-test.patch [new file with mode: 0644]
queue-5.10/selftests-powerpc-fix-resource-leaks.patch [new file with mode: 0644]
queue-5.10/serial-altera_uart-fix-locking-in-polling-mode.patch [new file with mode: 0644]
queue-5.10/serial-amba-pl011-avoid-sbsa-uart-accessing-dmacr-re.patch [new file with mode: 0644]
queue-5.10/serial-pch-fix-pci-device-refcount-leak-in-pch_reque.patch [new file with mode: 0644]
queue-5.10/serial-pl011-do-not-clear-rx-fifo-rx-interrupt-in-un.patch [new file with mode: 0644]
queue-5.10/serial-sunsab-fix-error-handling-in-sunsab_init.patch [new file with mode: 0644]
queue-5.10/serial-tegra-read-dma-status-before-terminating.patch [new file with mode: 0644]
queue-5.10/series [new file with mode: 0644]
queue-5.10/skbuff-account-for-tail-adjustment-during-pull-opera.patch [new file with mode: 0644]
queue-5.10/soc-qcom-apr-add-check-for-idr_alloc-and-of_property.patch [new file with mode: 0644]
queue-5.10/soc-qcom-apr-make-code-more-reuseable.patch [new file with mode: 0644]
queue-5.10/soc-qcom-llcc-make-irq-truly-optional.patch [new file with mode: 0644]
queue-5.10/soc-ti-knav_qmss_queue-fix-pm-disable-depth-imbalanc.patch [new file with mode: 0644]
queue-5.10/soc-ti-knav_qmss_queue-use-pm_runtime_resume_and_get.patch [new file with mode: 0644]
queue-5.10/soc-ti-smartreflex-fix-pm-disable-depth-imbalance-in.patch [new file with mode: 0644]
queue-5.10/spi-spi-gpio-don-t-set-mosi-as-an-input-if-not-3wire.patch [new file with mode: 0644]
queue-5.10/spi-spidev-mask-spi_cs_high-in-spi_ioc_rd_mode.patch [new file with mode: 0644]
queue-5.10/spi-update-reference-to-struct-spi_controller.patch [new file with mode: 0644]
queue-5.10/staging-rtl8192e-fix-potential-use-after-free-in-rtl.patch [new file with mode: 0644]
queue-5.10/staging-rtl8192u-fix-use-after-free-in-ieee80211_rx.patch [new file with mode: 0644]
queue-5.10/staging-vme_user-fix-possible-uaf-in-tsi148_dma_list.patch [new file with mode: 0644]
queue-5.10/stmmac-fix-potential-division-by-0.patch [new file with mode: 0644]
queue-5.10/sunrpc-fix-missing-release-socket-in-rpc_sockname.patch [new file with mode: 0644]
queue-5.10/test_firmware-fix-memory-leak-in-test_firmware_init.patch [new file with mode: 0644]
queue-5.10/thermal-drivers-imx8mm_thermal-validate-temperature-.patch [new file with mode: 0644]
queue-5.10/timerqueue-use-rb_entry_safe-in-timerqueue_getnext.patch [new file with mode: 0644]
queue-5.10/tpm-tpm_crb-fix-error-message-in-__crb_relinquish_lo.patch [new file with mode: 0644]
queue-5.10/tpm-tpm_ftpm_tee-fix-error-handling-in-ftpm_mod_init.patch [new file with mode: 0644]
queue-5.10/tracing-hist-fix-issue-of-losting-command-info-in-er.patch [new file with mode: 0644]
queue-5.10/tty-serial-altera_uart_-r-t-x_chars-need-only-uart_p.patch [new file with mode: 0644]
queue-5.10/tty-serial-clean-up-stop-tx-part-in-altera_uart_tx_c.patch [new file with mode: 0644]
queue-5.10/udf-avoid-double-brelse-in-udf_rename.patch [new file with mode: 0644]
queue-5.10/uio-uio_dmem_genirq-fix-deadlock-between-irq-config-.patch [new file with mode: 0644]
queue-5.10/uio-uio_dmem_genirq-fix-missing-unlock-in-irq-config.patch [new file with mode: 0644]
queue-5.10/uprobes-x86-allow-to-probe-a-nop-instruction-with-0x.patch [new file with mode: 0644]
queue-5.10/usb-fotg210-udc-fix-ages-old-endianness-issues.patch [new file with mode: 0644]
queue-5.10/usb-gadget-f_hid-fix-f_hidg-lifetime-vs-cdev.patch [new file with mode: 0644]
queue-5.10/usb-gadget-f_hid-fix-refcount-leak-on-error-path.patch [new file with mode: 0644]
queue-5.10/usb-gadget-f_hid-optional-setup-set_report-mode.patch [new file with mode: 0644]
queue-5.10/usb-musb-remove-extra-check-in-musb_gadget_vbus_draw.patch [new file with mode: 0644]
queue-5.10/usb-roles-fix-of-node-refcount-leak-in-usb_role_swit.patch [new file with mode: 0644]
queue-5.10/usb-storage-add-check-for-kcalloc.patch [new file with mode: 0644]
queue-5.10/usb-typec-check-for-ops-exit-instead-of-ops-enter-in.patch [new file with mode: 0644]
queue-5.10/usb-typec-tcpci-fix-of-node-refcount-leak-in-tcpci_r.patch [new file with mode: 0644]
queue-5.10/usb-typec-tipd-fix-spurious-fwnode_handle_put-in-err.patch [new file with mode: 0644]
queue-5.10/venus-pm_helpers-fix-error-check-in-vcodec_domains_g.patch [new file with mode: 0644]
queue-5.10/vfio-platform-do-not-pass-return-buffer-to-acpi-_rst.patch [new file with mode: 0644]
queue-5.10/video-hyperv_fb-avoid-taking-busy-spinlock-on-panic-.patch [new file with mode: 0644]
queue-5.10/vme-fix-error-not-catched-in-fake_init.patch [new file with mode: 0644]
queue-5.10/wifi-ar5523-fix-use-after-free-on-ar5523_cmd-timed-o.patch [new file with mode: 0644]
queue-5.10/wifi-ath10k-fix-return-value-in-ath10k_pci_init.patch [new file with mode: 0644]
queue-5.10/wifi-ath9k-hif_usb-fix-memory-leak-of-urbs-in-ath9k_.patch [new file with mode: 0644]
queue-5.10/wifi-ath9k-hif_usb-fix-use-after-free-in-ath9k_hif_u.patch [new file with mode: 0644]
queue-5.10/wifi-ath9k-verify-the-expected-usb_endpoints-are-pre.patch [new file with mode: 0644]
queue-5.10/wifi-brcmfmac-fix-error-return-code-in-brcmf_sdio_do.patch [new file with mode: 0644]
queue-5.10/wifi-brcmfmac-fix-potential-shift-out-of-bounds-in-b.patch [new file with mode: 0644]
queue-5.10/wifi-cfg80211-fix-not-unregister-reg_pdev-when-load_.patch [new file with mode: 0644]
queue-5.10/wifi-iwlwifi-mvm-fix-double-free-on-tx-path.patch [new file with mode: 0644]
queue-5.10/wifi-mac80211-fix-memory-leak-in-ieee80211_if_add.patch [new file with mode: 0644]
queue-5.10/wifi-mt76-fix-coverity-overrun-call-in-mt76_get_txpo.patch [new file with mode: 0644]
queue-5.10/wifi-rsi-fix-handling-of-802.3-eapol-frames-sent-via.patch [new file with mode: 0644]
queue-5.10/wifi-rtl8xxxu-add-__packed-to-struct-rtl8723bu_c2h.patch [new file with mode: 0644]
queue-5.10/wifi-rtl8xxxu-fix-reading-the-vendor-of-combo-chips.patch [new file with mode: 0644]
queue-5.10/wifi-rtl8xxxu-fix-the-channel-width-reporting.patch [new file with mode: 0644]
queue-5.10/x86-hyperv-remove-unregister-syscore-call-from-hyper.patch [new file with mode: 0644]
queue-5.10/x86-xen-fix-memory-leak-in-xen_init_lock_cpu.patch [new file with mode: 0644]
queue-5.10/x86-xen-fix-memory-leak-in-xen_smp_intr_init-_pv.patch [new file with mode: 0644]
queue-5.10/xen-privcmd-fix-a-possible-warning-in-privcmd_ioctl_.patch [new file with mode: 0644]
queue-5.10/xprtrdma-fix-regbuf-data-not-freed-in-rpcrdma_req_cr.patch [new file with mode: 0644]

diff --git a/queue-5.10/acct-fix-potential-integer-overflow-in-encode_comp_t.patch b/queue-5.10/acct-fix-potential-integer-overflow-in-encode_comp_t.patch
new file mode 100644 (file)
index 0000000..b85add1
--- /dev/null
@@ -0,0 +1,51 @@
+From 902ca5ffbb9777e8138dba92354ef9198b1078f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 May 2021 22:06:31 +0800
+Subject: acct: fix potential integer overflow in encode_comp_t()
+
+From: Zheng Yejian <zhengyejian1@huawei.com>
+
+[ Upstream commit c5f31c655bcc01b6da53b836ac951c1556245305 ]
+
+The integer overflow is descripted with following codes:
+  > 317 static comp_t encode_comp_t(u64 value)
+  > 318 {
+  > 319         int exp, rnd;
+    ......
+  > 341         exp <<= MANTSIZE;
+  > 342         exp += value;
+  > 343         return exp;
+  > 344 }
+
+Currently comp_t is defined as type of '__u16', but the variable 'exp' is
+type of 'int', so overflow would happen when variable 'exp' in line 343 is
+greater than 65535.
+
+Link: https://lkml.kernel.org/r/20210515140631.369106-3-zhengyejian1@huawei.com
+Signed-off-by: Zheng Yejian <zhengyejian1@huawei.com>
+Cc: Hanjun Guo <guohanjun@huawei.com>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Zhang Jinhao <zhangjinhao2@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/acct.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/kernel/acct.c b/kernel/acct.c
+index f175df8f6aa4..12f7dacf560e 100644
+--- a/kernel/acct.c
++++ b/kernel/acct.c
+@@ -331,6 +331,8 @@ static comp_t encode_comp_t(unsigned long value)
+               exp++;
+       }
++      if (exp > (((comp_t) ~0U) >> MANTSIZE))
++              return (comp_t) ~0U;
+       /*
+        * Clean it up and polish it off.
+        */
+-- 
+2.35.1
+
diff --git a/queue-5.10/acpica-fix-error-code-path-in-acpi_ds_call_control_m.patch b/queue-5.10/acpica-fix-error-code-path-in-acpi_ds_call_control_m.patch
new file mode 100644 (file)
index 0000000..8cf5737
--- /dev/null
@@ -0,0 +1,68 @@
+From bea8f144ec6482b988a8c67772cd41f00fdeb71c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Nov 2022 18:42:36 +0100
+Subject: ACPICA: Fix error code path in acpi_ds_call_control_method()
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 404ec60438add1afadaffaed34bb5fe4ddcadd40 ]
+
+A use-after-free in acpi_ps_parse_aml() after a failing invocaion of
+acpi_ds_call_control_method() is reported by KASAN [1] and code
+inspection reveals that next_walk_state pushed to the thread by
+acpi_ds_create_walk_state() is freed on errors, but it is not popped
+from the thread beforehand.  Thus acpi_ds_get_current_walk_state()
+called by acpi_ps_parse_aml() subsequently returns it as the new
+walk state which is incorrect.
+
+To address this, make acpi_ds_call_control_method() call
+acpi_ds_pop_walk_state() to pop next_walk_state from the thread before
+returning an error.
+
+Link: https://lore.kernel.org/linux-acpi/20221019073443.248215-1-chenzhongjin@huawei.com/ # [1]
+Reported-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpica/dsmethod.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c
+index cf67caff878a..97971c79c5f5 100644
+--- a/drivers/acpi/acpica/dsmethod.c
++++ b/drivers/acpi/acpica/dsmethod.c
+@@ -517,7 +517,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
+       info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+       if (!info) {
+               status = AE_NO_MEMORY;
+-              goto cleanup;
++              goto pop_walk_state;
+       }
+       info->parameters = &this_walk_state->operands[0];
+@@ -529,7 +529,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
+       ACPI_FREE(info);
+       if (ACPI_FAILURE(status)) {
+-              goto cleanup;
++              goto pop_walk_state;
+       }
+       next_walk_state->method_nesting_depth =
+@@ -575,6 +575,12 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
+       return_ACPI_STATUS(status);
++pop_walk_state:
++
++      /* On error, pop the walk state to be deleted from thread */
++
++      acpi_ds_pop_walk_state(thread);
++
+ cleanup:
+       /* On error, we must terminate the method properly */
+-- 
+2.35.1
+
diff --git a/queue-5.10/acpica-fix-use-after-free-in-acpi_ut_copy_ipackage_t.patch b/queue-5.10/acpica-fix-use-after-free-in-acpi_ut_copy_ipackage_t.patch
new file mode 100644 (file)
index 0000000..a34aba6
--- /dev/null
@@ -0,0 +1,70 @@
+From 766c2e3dd456060f256557aa73e52c911e2daef3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 16:05:14 +0800
+Subject: ACPICA: Fix use-after-free in acpi_ut_copy_ipackage_to_ipackage()
+
+From: Li Zetao <lizetao1@huawei.com>
+
+[ Upstream commit 470188b09e92d83c5a997f25f0e8fb8cd2bc3469 ]
+
+There is an use-after-free reported by KASAN:
+
+  BUG: KASAN: use-after-free in acpi_ut_remove_reference+0x3b/0x82
+  Read of size 1 at addr ffff888112afc460 by task modprobe/2111
+  CPU: 0 PID: 2111 Comm: modprobe Not tainted 6.1.0-rc7-dirty
+  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
+  Call Trace:
+   <TASK>
+   kasan_report+0xae/0xe0
+   acpi_ut_remove_reference+0x3b/0x82
+   acpi_ut_copy_iobject_to_iobject+0x3be/0x3d5
+   acpi_ds_store_object_to_local+0x15d/0x3a0
+   acpi_ex_store+0x78d/0x7fd
+   acpi_ex_opcode_1A_1T_1R+0xbe4/0xf9b
+   acpi_ps_parse_aml+0x217/0x8d5
+   ...
+   </TASK>
+
+The root cause of the problem is that the acpi_operand_object
+is freed when acpi_ut_walk_package_tree() fails in
+acpi_ut_copy_ipackage_to_ipackage(), lead to repeated release in
+acpi_ut_copy_iobject_to_iobject(). The problem was introduced
+by "8aa5e56eeb61" commit, this commit is to fix memory leak in
+acpi_ut_copy_iobject_to_iobject(), repeatedly adding remove
+operation, lead to "acpi_operand_object" used after free.
+
+Fix it by removing acpi_ut_remove_reference() in
+acpi_ut_copy_ipackage_to_ipackage(). acpi_ut_copy_ipackage_to_ipackage()
+is called to copy an internal package object into another internal
+package object, when it fails, the memory of acpi_operand_object
+should be freed by the caller.
+
+Fixes: 8aa5e56eeb61 ("ACPICA: Utilities: Fix memory leak in acpi_ut_copy_iobject_to_iobject")
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpica/utcopy.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
+index 41bdd0278dd8..9a7cc679e544 100644
+--- a/drivers/acpi/acpica/utcopy.c
++++ b/drivers/acpi/acpica/utcopy.c
+@@ -916,13 +916,6 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
+       status = acpi_ut_walk_package_tree(source_obj, dest_obj,
+                                          acpi_ut_copy_ielement_to_ielement,
+                                          walk_state);
+-      if (ACPI_FAILURE(status)) {
+-
+-              /* On failure, delete the destination package object */
+-
+-              acpi_ut_remove_reference(dest_obj);
+-      }
+-
+       return_ACPI_STATUS(status);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/alpha-fix-syscall-entry-in-audut_syscall-case.patch b/queue-5.10/alpha-fix-syscall-entry-in-audut_syscall-case.patch
new file mode 100644 (file)
index 0000000..2fe6928
--- /dev/null
@@ -0,0 +1,40 @@
+From 57dd8a9a398eff8fb7a12c389579d7866e32fa2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Sep 2021 18:18:48 -0400
+Subject: alpha: fix syscall entry in !AUDUT_SYSCALL case
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit f7b2431a6d22f7a91c567708e071dfcd6d66db14 ]
+
+We only want to take the slow path if SYSCALL_TRACE or SYSCALL_AUDIT is
+set; on !AUDIT_SYSCALL configs the current tree hits it whenever _any_
+thread flag (including NEED_RESCHED, NOTIFY_SIGNAL, etc.) happens to
+be set.
+
+Fixes: a9302e843944 "alpha: Enable system-call auditing support"
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/alpha/kernel/entry.S | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
+index 2e09248f8324..c27d01232799 100644
+--- a/arch/alpha/kernel/entry.S
++++ b/arch/alpha/kernel/entry.S
+@@ -469,8 +469,10 @@ entSys:
+ #ifdef CONFIG_AUDITSYSCALL
+       lda     $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+       and     $3, $6, $3
+-#endif
+       bne     $3, strace
++#else
++      blbs    $3, strace              /* check for SYSCALL_TRACE in disguise */
++#endif
+       beq     $4, 1f
+       ldq     $27, 0($5)
+ 1:    jsr     $26, ($27), sys_ni_syscall
+-- 
+2.35.1
+
diff --git a/queue-5.10/alsa-asihpi-fix-missing-pci_disable_device.patch b/queue-5.10/alsa-asihpi-fix-missing-pci_disable_device.patch
new file mode 100644 (file)
index 0000000..127a2db
--- /dev/null
@@ -0,0 +1,37 @@
+From d9fbc932dc0558267d180d988f9a859eeb762525 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Nov 2022 10:14:29 +0800
+Subject: ALSA: asihpi: fix missing pci_disable_device()
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+[ Upstream commit 9d86515c3d4c0564a0c31a2df87d735353a1971e ]
+
+pci_disable_device() need be called while module exiting, switch to use
+pcim_enable(), pci_disable_device() will be called in pcim_release().
+
+Fixes: 3285ea10e9b0 ("ALSA: asihpi - Interrelated HPI tidy up.")
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Link: https://lore.kernel.org/r/20221126021429.3029562-1-liushixin2@huawei.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/asihpi/hpioctl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
+index bb31b7fe867d..477a5b4b50bc 100644
+--- a/sound/pci/asihpi/hpioctl.c
++++ b/sound/pci/asihpi/hpioctl.c
+@@ -361,7 +361,7 @@ int asihpi_adapter_probe(struct pci_dev *pci_dev,
+               pci_dev->device, pci_dev->subsystem_vendor,
+               pci_dev->subsystem_device, pci_dev->devfn);
+-      if (pci_enable_device(pci_dev) < 0) {
++      if (pcim_enable_device(pci_dev) < 0) {
+               dev_err(&pci_dev->dev,
+                       "pci_enable_device failed, disabling device\n");
+               return -EIO;
+-- 
+2.35.1
+
diff --git a/queue-5.10/alsa-mts64-fix-possible-null-ptr-defer-in-snd_mts64_.patch b/queue-5.10/alsa-mts64-fix-possible-null-ptr-defer-in-snd_mts64_.patch
new file mode 100644 (file)
index 0000000..a4b6c74
--- /dev/null
@@ -0,0 +1,103 @@
+From 9a09cffcf85e2faebbdafeb14899c9b928dacf34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 14:10:04 +0800
+Subject: ALSA: mts64: fix possible null-ptr-defer in snd_mts64_interrupt
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit cf2ea3c86ad90d63d1c572b43e1ca9276b0357ad ]
+
+I got a null-ptr-defer error report when I do the following tests
+on the qemu platform:
+
+make defconfig and CONFIG_PARPORT=m, CONFIG_PARPORT_PC=m,
+CONFIG_SND_MTS64=m
+
+Then making test scripts:
+cat>test_mod1.sh<<EOF
+modprobe snd-mts64
+modprobe snd-mts64
+EOF
+
+Executing the script, perhaps several times, we will get a null-ptr-defer
+report, as follow:
+
+syzkaller:~# ./test_mod.sh
+snd_mts64: probe of snd_mts64.0 failed with error -5
+modprobe: ERROR: could not insert 'snd_mts64': No such device
+ BUG: kernel NULL pointer dereference, address: 0000000000000000
+ #PF: supervisor write access in kernel mode
+ #PF: error_code(0x0002) - not-present page
+ PGD 0 P4D 0
+ Oops: 0002 [#1] PREEMPT SMP PTI
+ CPU: 0 PID: 205 Comm: modprobe Not tainted 6.1.0-rc8-00588-g76dcd734eca2 #6
+ Call Trace:
+  <IRQ>
+  snd_mts64_interrupt+0x24/0xa0 [snd_mts64]
+  parport_irq_handler+0x37/0x50 [parport]
+  __handle_irq_event_percpu+0x39/0x190
+  handle_irq_event_percpu+0xa/0x30
+  handle_irq_event+0x2f/0x50
+  handle_edge_irq+0x99/0x1b0
+  __common_interrupt+0x5d/0x100
+  common_interrupt+0xa0/0xc0
+  </IRQ>
+  <TASK>
+  asm_common_interrupt+0x22/0x40
+ RIP: 0010:_raw_write_unlock_irqrestore+0x11/0x30
+  parport_claim+0xbd/0x230 [parport]
+  snd_mts64_probe+0x14a/0x465 [snd_mts64]
+  platform_probe+0x3f/0xa0
+  really_probe+0x129/0x2c0
+  __driver_probe_device+0x6d/0xc0
+  driver_probe_device+0x1a/0xa0
+  __device_attach_driver+0x7a/0xb0
+  bus_for_each_drv+0x62/0xb0
+  __device_attach+0xe4/0x180
+  bus_probe_device+0x82/0xa0
+  device_add+0x550/0x920
+  platform_device_add+0x106/0x220
+  snd_mts64_attach+0x2e/0x80 [snd_mts64]
+  port_check+0x14/0x20 [parport]
+  bus_for_each_dev+0x6e/0xc0
+  __parport_register_driver+0x7c/0xb0 [parport]
+  snd_mts64_module_init+0x31/0x1000 [snd_mts64]
+  do_one_initcall+0x3c/0x1f0
+  do_init_module+0x46/0x1c6
+  load_module+0x1d8d/0x1e10
+  __do_sys_finit_module+0xa2/0xf0
+  do_syscall_64+0x37/0x90
+  entry_SYSCALL_64_after_hwframe+0x63/0xcd
+  </TASK>
+ Kernel panic - not syncing: Fatal exception in interrupt
+ Rebooting in 1 seconds..
+
+The mts wa not initialized during interrupt,  we add check for
+mts to fix this bug.
+
+Fixes: 68ab801e32bb ("[ALSA] Add snd-mts64 driver for ESI Miditerminal 4140")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Link: https://lore.kernel.org/r/20221206061004.1222966-1-cuigaosheng1@huawei.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/drivers/mts64.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
+index 9c708b693cb3..257314920e4d 100644
+--- a/sound/drivers/mts64.c
++++ b/sound/drivers/mts64.c
+@@ -816,6 +816,9 @@ static void snd_mts64_interrupt(void *private)
+       u8 status, data;
+       struct snd_rawmidi_substream *substream;
++      if (!mts)
++              return;
++
+       spin_lock(&mts->lock);
+       ret = mts64_read(mts->pardev->port);
+       data = ret & 0x00ff;
+-- 
+2.35.1
+
diff --git a/queue-5.10/alsa-pcm-fix-undefined-behavior-in-bit-shift-for-snd.patch b/queue-5.10/alsa-pcm-fix-undefined-behavior-in-bit-shift-for-snd.patch
new file mode 100644 (file)
index 0000000..bbaf4d9
--- /dev/null
@@ -0,0 +1,92 @@
+From ed52f4934243d5a2fcdfb424c255b3cbd869bacf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 19:00:44 +0800
+Subject: ALSA: pcm: fix undefined behavior in bit shift for
+ SNDRV_PCM_RATE_KNOT
+
+From: Baisong Zhong <zhongbaisong@huawei.com>
+
+[ Upstream commit b5172e62458f8e6ff359e5f096044a488db90ac5 ]
+
+Shifting signed 32-bit value by 31 bits is undefined, so changing
+significant bit to unsigned. The UBSAN warning calltrace like below:
+
+UBSAN: shift-out-of-bounds in sound/core/pcm_native.c:2676:21
+left shift of 1 by 31 places cannot be represented in type 'int'
+...
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x8d/0xcf
+ ubsan_epilogue+0xa/0x44
+ __ubsan_handle_shift_out_of_bounds+0x1e7/0x208
+ snd_pcm_open_substream+0x9f0/0xa90
+ snd_pcm_oss_open.part.26+0x313/0x670
+ snd_pcm_oss_open+0x30/0x40
+ soundcore_open+0x18b/0x2e0
+ chrdev_open+0xe2/0x270
+ do_dentry_open+0x2f7/0x620
+ path_openat+0xd66/0xe70
+ do_filp_open+0xe3/0x170
+ do_sys_openat2+0x357/0x4a0
+ do_sys_open+0x87/0xd0
+ do_syscall_64+0x34/0x80
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Baisong Zhong <zhongbaisong@huawei.com>
+Link: https://lore.kernel.org/r/20221121110044.3115686-1-zhongbaisong@huawei.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/sound/pcm.h | 36 ++++++++++++++++++------------------
+ 1 file changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/include/sound/pcm.h b/include/sound/pcm.h
+index 5ffc2efedd9f..6554a9f71c62 100644
+--- a/include/sound/pcm.h
++++ b/include/sound/pcm.h
+@@ -106,24 +106,24 @@ struct snd_pcm_ops {
+ #define SNDRV_PCM_POS_XRUN            ((snd_pcm_uframes_t)-1)
+ /* If you change this don't forget to change rates[] table in pcm_native.c */
+-#define SNDRV_PCM_RATE_5512           (1<<0)          /* 5512Hz */
+-#define SNDRV_PCM_RATE_8000           (1<<1)          /* 8000Hz */
+-#define SNDRV_PCM_RATE_11025          (1<<2)          /* 11025Hz */
+-#define SNDRV_PCM_RATE_16000          (1<<3)          /* 16000Hz */
+-#define SNDRV_PCM_RATE_22050          (1<<4)          /* 22050Hz */
+-#define SNDRV_PCM_RATE_32000          (1<<5)          /* 32000Hz */
+-#define SNDRV_PCM_RATE_44100          (1<<6)          /* 44100Hz */
+-#define SNDRV_PCM_RATE_48000          (1<<7)          /* 48000Hz */
+-#define SNDRV_PCM_RATE_64000          (1<<8)          /* 64000Hz */
+-#define SNDRV_PCM_RATE_88200          (1<<9)          /* 88200Hz */
+-#define SNDRV_PCM_RATE_96000          (1<<10)         /* 96000Hz */
+-#define SNDRV_PCM_RATE_176400         (1<<11)         /* 176400Hz */
+-#define SNDRV_PCM_RATE_192000         (1<<12)         /* 192000Hz */
+-#define SNDRV_PCM_RATE_352800         (1<<13)         /* 352800Hz */
+-#define SNDRV_PCM_RATE_384000         (1<<14)         /* 384000Hz */
+-
+-#define SNDRV_PCM_RATE_CONTINUOUS     (1<<30)         /* continuous range */
+-#define SNDRV_PCM_RATE_KNOT           (1<<31)         /* supports more non-continuos rates */
++#define SNDRV_PCM_RATE_5512           (1U<<0)         /* 5512Hz */
++#define SNDRV_PCM_RATE_8000           (1U<<1)         /* 8000Hz */
++#define SNDRV_PCM_RATE_11025          (1U<<2)         /* 11025Hz */
++#define SNDRV_PCM_RATE_16000          (1U<<3)         /* 16000Hz */
++#define SNDRV_PCM_RATE_22050          (1U<<4)         /* 22050Hz */
++#define SNDRV_PCM_RATE_32000          (1U<<5)         /* 32000Hz */
++#define SNDRV_PCM_RATE_44100          (1U<<6)         /* 44100Hz */
++#define SNDRV_PCM_RATE_48000          (1U<<7)         /* 48000Hz */
++#define SNDRV_PCM_RATE_64000          (1U<<8)         /* 64000Hz */
++#define SNDRV_PCM_RATE_88200          (1U<<9)         /* 88200Hz */
++#define SNDRV_PCM_RATE_96000          (1U<<10)        /* 96000Hz */
++#define SNDRV_PCM_RATE_176400         (1U<<11)        /* 176400Hz */
++#define SNDRV_PCM_RATE_192000         (1U<<12)        /* 192000Hz */
++#define SNDRV_PCM_RATE_352800         (1U<<13)        /* 352800Hz */
++#define SNDRV_PCM_RATE_384000         (1U<<14)        /* 384000Hz */
++
++#define SNDRV_PCM_RATE_CONTINUOUS     (1U<<30)        /* continuous range */
++#define SNDRV_PCM_RATE_KNOT           (1U<<31)        /* supports more non-continuos rates */
+ #define SNDRV_PCM_RATE_8000_44100     (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
+                                        SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|\
+-- 
+2.35.1
+
diff --git a/queue-5.10/alsa-pcm-set-missing-stop_operating-flag-at-undoing-.patch b/queue-5.10/alsa-pcm-set-missing-stop_operating-flag-at-undoing-.patch
new file mode 100644 (file)
index 0000000..49dc4ed
--- /dev/null
@@ -0,0 +1,46 @@
+From 04e609d509deb59d1c5be107191834769b4a638d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 14:21:22 +0100
+Subject: ALSA: pcm: Set missing stop_operating flag at undoing trigger start
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 5c8cc93b06d1ff860327a273abf3ac006290d242 ]
+
+When a PCM trigger-start fails at snd_pcm_do_start(), PCM core tries
+to undo the action at snd_pcm_undo_start() by issuing the trigger STOP
+manually.  At that point, we forgot to set the stop_operating flag,
+hence the sync-stop won't be issued at the next prepare or other
+calls.
+
+This patch adds the missing stop_operating flag at
+snd_pcm_undo_start().
+
+Fixes: 1e850beea278 ("ALSA: pcm: Add the support for sync-stop operation")
+Link: https://lore.kernel.org/r/b4e71631-4a94-613-27b2-fb595792630@carlh.net
+Link: https://lore.kernel.org/r/20221205132124.11585-2-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/pcm_native.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
+index 6cc7c2a9fe73..9425fcd30c4c 100644
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -1413,8 +1413,10 @@ static int snd_pcm_do_start(struct snd_pcm_substream *substream,
+ static void snd_pcm_undo_start(struct snd_pcm_substream *substream,
+                              snd_pcm_state_t state)
+ {
+-      if (substream->runtime->trigger_master == substream)
++      if (substream->runtime->trigger_master == substream) {
+               substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
++              substream->runtime->stop_operating = true;
++      }
+ }
+ static void snd_pcm_post_start(struct snd_pcm_substream *substream,
+-- 
+2.35.1
+
diff --git a/queue-5.10/alsa-seq-fix-undefined-behavior-in-bit-shift-for-snd.patch b/queue-5.10/alsa-seq-fix-undefined-behavior-in-bit-shift-for-snd.patch
new file mode 100644 (file)
index 0000000..b093245
--- /dev/null
@@ -0,0 +1,66 @@
+From c3c42b5b13cea427d5f250353ca3b113997e07c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 19:16:30 +0800
+Subject: ALSA: seq: fix undefined behavior in bit shift for
+ SNDRV_SEQ_FILTER_USE_EVENT
+
+From: Baisong Zhong <zhongbaisong@huawei.com>
+
+[ Upstream commit cf59e1e4c79bf741905484cdb13c130b53576a16 ]
+
+Shifting signed 32-bit value by 31 bits is undefined, so changing
+significant bit to unsigned. The UBSAN warning calltrace like below:
+
+UBSAN: shift-out-of-bounds in sound/core/seq/seq_clientmgr.c:509:22
+left shift of 1 by 31 places cannot be represented in type 'int'
+...
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x8d/0xcf
+ ubsan_epilogue+0xa/0x44
+ __ubsan_handle_shift_out_of_bounds+0x1e7/0x208
+ snd_seq_deliver_single_event.constprop.21+0x191/0x2f0
+ snd_seq_deliver_event+0x1a2/0x350
+ snd_seq_kernel_client_dispatch+0x8b/0xb0
+ snd_seq_client_notify_subscription+0x72/0xa0
+ snd_seq_ioctl_subscribe_port+0x128/0x160
+ snd_seq_kernel_client_ctl+0xce/0xf0
+ snd_seq_oss_create_client+0x109/0x15b
+ alsa_seq_oss_init+0x11c/0x1aa
+ do_one_initcall+0x80/0x440
+ kernel_init_freeable+0x370/0x3c3
+ kernel_init+0x1b/0x190
+ ret_from_fork+0x1f/0x30
+ </TASK>
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Baisong Zhong <zhongbaisong@huawei.com>
+Link: https://lore.kernel.org/r/20221121111630.3119259-1-zhongbaisong@huawei.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/sound/asequencer.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/uapi/sound/asequencer.h b/include/uapi/sound/asequencer.h
+index a75e14edc957..dbd60f48b4b0 100644
+--- a/include/uapi/sound/asequencer.h
++++ b/include/uapi/sound/asequencer.h
+@@ -344,10 +344,10 @@ typedef int __bitwise snd_seq_client_type_t;
+ #define       KERNEL_CLIENT   ((__force snd_seq_client_type_t) 2)
+                         
+       /* event filter flags */
+-#define SNDRV_SEQ_FILTER_BROADCAST    (1<<0)  /* accept broadcast messages */
+-#define SNDRV_SEQ_FILTER_MULTICAST    (1<<1)  /* accept multicast messages */
+-#define SNDRV_SEQ_FILTER_BOUNCE               (1<<2)  /* accept bounce event in error */
+-#define SNDRV_SEQ_FILTER_USE_EVENT    (1<<31) /* use event filter */
++#define SNDRV_SEQ_FILTER_BROADCAST    (1U<<0) /* accept broadcast messages */
++#define SNDRV_SEQ_FILTER_MULTICAST    (1U<<1) /* accept multicast messages */
++#define SNDRV_SEQ_FILTER_BOUNCE               (1U<<2) /* accept bounce event in error */
++#define SNDRV_SEQ_FILTER_USE_EVENT    (1U<<31)        /* use event filter */
+ struct snd_seq_client_info {
+       int client;                     /* client number to inquire */
+-- 
+2.35.1
+
diff --git a/queue-5.10/amdgpu-pm-prevent-array-underflow-in-vega20_odn_edit.patch b/queue-5.10/amdgpu-pm-prevent-array-underflow-in-vega20_odn_edit.patch
new file mode 100644 (file)
index 0000000..96ff68c
--- /dev/null
@@ -0,0 +1,38 @@
+From d3aee9af6dca7702e70de2f564f81084570dfb8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 15:56:57 +0300
+Subject: amdgpu/pm: prevent array underflow in vega20_odn_edit_dpm_table()
+
+From: Dan Carpenter <error27@gmail.com>
+
+[ Upstream commit d27252b5706e51188aed7647126e44dcf9e940c1 ]
+
+In the PP_OD_EDIT_VDDC_CURVE case the "input_index" variable is capped at
+2 but not checked for negative values so it results in an out of bounds
+read.  This value comes from the user via sysfs.
+
+Fixes: d5bf26539494 ("drm/amd/powerplay: added vega20 overdrive support V3")
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
+index 60cde0c52825..57a354a03e8a 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
+@@ -2962,7 +2962,8 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
+                       data->od8_settings.od8_settings_array;
+       OverDriveTable_t *od_table =
+                       &(data->smc_state_table.overdrive_table);
+-      int32_t input_index, input_clk, input_vol, i;
++      int32_t input_clk, input_vol, i;
++      uint32_t input_index;
+       int od8_id;
+       int ret;
+-- 
+2.35.1
+
diff --git a/queue-5.10/apparmor-fix-a-memleak-in-multi_transaction_new.patch b/queue-5.10/apparmor-fix-a-memleak-in-multi_transaction_new.patch
new file mode 100644 (file)
index 0000000..fa8c27f
--- /dev/null
@@ -0,0 +1,42 @@
+From ca78badc13eb4fda8c569d2774237aa011b3f49d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Aug 2022 09:15:03 +0800
+Subject: apparmor: fix a memleak in multi_transaction_new()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit c73275cf6834787ca090317f1d20dbfa3b7f05aa ]
+
+In multi_transaction_new(), the variable t is not freed or passed out
+on the failure of copy_from_user(t->data, buf, size), which could lead
+to a memleak.
+
+Fix this bug by adding a put_multi_transaction(t) in the error path.
+
+Fixes: 1dea3b41e84c5 ("apparmor: speed up transactional queries")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/apparmorfs.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index c173f6fd7aee..49d97b331abc 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -867,8 +867,10 @@ static struct multi_transaction *multi_transaction_new(struct file *file,
+       if (!t)
+               return ERR_PTR(-ENOMEM);
+       kref_init(&t->count);
+-      if (copy_from_user(t->data, buf, size))
++      if (copy_from_user(t->data, buf, size)) {
++              put_multi_transaction(t);
+               return ERR_PTR(-EFAULT);
++      }
+       return t;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/apparmor-fix-abi-check-to-include-v8-abi.patch b/queue-5.10/apparmor-fix-abi-check-to-include-v8-abi.patch
new file mode 100644 (file)
index 0000000..1678fc8
--- /dev/null
@@ -0,0 +1,42 @@
+From 672b7688cfd428c227d3680f04a86a1c8624a6a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 May 2022 18:57:12 -0700
+Subject: apparmor: Fix abi check to include v8 abi
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 1b5a6198f5a9d0aa5497da0dc4bcd4fc166ee516 ]
+
+The v8 abi is supported by the kernel but the userspace supported
+version check does not allow for it. This was missed when v8 was added
+due to a bug in the userspace compiler which was setting an older abi
+version for v8 encoding (which is forward compatible except on the
+network encoding). However it is possible to detect the network
+encoding by checking the policydb network support which the code
+does. The end result was that missing the abi flag worked until
+userspace was fixed and began correctly checking for the v8 abi
+version.
+
+Fixes: 56974a6fcfef ("apparmor: add base infastructure for socket mediation")
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy_unpack.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index 556ef65ab6ee..519656e68582 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -964,7 +964,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns)
+        * if not specified use previous version
+        * Mask off everything that is not kernel abi version
+        */
+-      if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) {
++      if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v8)) {
+               audit_iface(NULL, NULL, NULL, "unsupported interface version",
+                           e, error);
+               return error;
+-- 
+2.35.1
+
diff --git a/queue-5.10/apparmor-fix-lockdep-warning-when-removing-a-namespa.patch b/queue-5.10/apparmor-fix-lockdep-warning-when-removing-a-namespa.patch
new file mode 100644 (file)
index 0000000..4bbec9e
--- /dev/null
@@ -0,0 +1,56 @@
+From b761fd684ba605a6bca1bab5cc7c8d2652ed2831 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Sep 2022 03:39:55 -0700
+Subject: apparmor: fix lockdep warning when removing a namespace
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 9c4557efc558a68e4cd973490fd936d6e3414db8 ]
+
+Fix the following lockdep warning
+
+[ 1119.158984] ============================================
+[ 1119.158988] WARNING: possible recursive locking detected
+[ 1119.158996] 6.0.0-rc1+ #257 Tainted: G            E    N
+[ 1119.158999] --------------------------------------------
+[ 1119.159001] bash/80100 is trying to acquire lock:
+[ 1119.159007] ffff88803e79b4a0 (&ns->lock/1){+.+.}-{4:4}, at: destroy_ns.part.0+0x43/0x140
+[ 1119.159028]
+               but task is already holding lock:
+[ 1119.159030] ffff8881009764a0 (&ns->lock/1){+.+.}-{4:4}, at: aa_remove_profiles+0x3f0/0x640
+[ 1119.159040]
+               other info that might help us debug this:
+[ 1119.159042]  Possible unsafe locking scenario:
+
+[ 1119.159043]        CPU0
+[ 1119.159045]        ----
+[ 1119.159047]   lock(&ns->lock/1);
+[ 1119.159051]   lock(&ns->lock/1);
+[ 1119.159055]
+                *** DEADLOCK ***
+
+Which is caused by an incorrect lockdep nesting notation
+
+Fixes: feb3c766a3ab ("apparmor: fix possible recursive lock warning in __aa_create_ns")
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
+index 4c010c9a6af1..fcf22577f606 100644
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -1125,7 +1125,7 @@ ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_label *subj,
+       if (!name) {
+               /* remove namespace - can only happen if fqname[0] == ':' */
+-              mutex_lock_nested(&ns->parent->lock, ns->level);
++              mutex_lock_nested(&ns->parent->lock, ns->parent->level);
+               __aa_bump_ns_revision(ns);
+               __aa_remove_ns(ns);
+               mutex_unlock(&ns->parent->lock);
+-- 
+2.35.1
+
diff --git a/queue-5.10/apparmor-fix-memleak-in-alloc_ns.patch b/queue-5.10/apparmor-fix-memleak-in-alloc_ns.patch
new file mode 100644 (file)
index 0000000..fe0b821
--- /dev/null
@@ -0,0 +1,38 @@
+From 90d93ecc73a025f4c3263be18142f8975d1a8d74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Oct 2022 20:33:20 +0800
+Subject: apparmor: Fix memleak in alloc_ns()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit e9e6fa49dbab6d84c676666f3fe7d360497fd65b ]
+
+After changes in commit a1bd627b46d1 ("apparmor: share profile name on
+replacement"), the hname member of struct aa_policy is not valid slab
+object, but a subset of that, it can not be freed by kfree_sensitive(),
+use aa_policy_destroy() to fix it.
+
+Fixes: a1bd627b46d1 ("apparmor: share profile name on replacement")
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy_ns.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
+index 70921d95fb40..53d24cf63893 100644
+--- a/security/apparmor/policy_ns.c
++++ b/security/apparmor/policy_ns.c
+@@ -121,7 +121,7 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
+       return ns;
+ fail_unconfined:
+-      kfree_sensitive(ns->base.hname);
++      aa_policy_destroy(&ns->base);
+ fail_ns:
+       kfree_sensitive(ns);
+       return NULL;
+-- 
+2.35.1
+
diff --git a/queue-5.10/apparmor-use-pointer-to-struct-aa_label-for-lbs_cred.patch b/queue-5.10/apparmor-use-pointer-to-struct-aa_label-for-lbs_cred.patch
new file mode 100644 (file)
index 0000000..a70f0b2
--- /dev/null
@@ -0,0 +1,41 @@
+From acb3212efee5d8e0237028f2a3dda8f95ede79d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Oct 2022 08:46:04 +0800
+Subject: apparmor: Use pointer to struct aa_label for lbs_cred
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 37923d4321b1e38170086da2c117f78f2b0f49c6 ]
+
+According to the implementations of cred_label() and set_cred_label(),
+we should use pointer to struct aa_label for lbs_cred instead of struct
+aa_task_ctx, this patch fixes it.
+
+Fixes: bbd3662a8348 ("Infrastructure management of the cred security blob")
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lsm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index ffeaee5ed968..585edcc6814d 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -1161,10 +1161,10 @@ static int apparmor_inet_conn_request(struct sock *sk, struct sk_buff *skb,
+ #endif
+ /*
+- * The cred blob is a pointer to, not an instance of, an aa_task_ctx.
++ * The cred blob is a pointer to, not an instance of, an aa_label.
+  */
+ struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = {
+-      .lbs_cred = sizeof(struct aa_task_ctx *),
++      .lbs_cred = sizeof(struct aa_label *),
+       .lbs_file = sizeof(struct aa_file_ctx),
+       .lbs_task = sizeof(struct aa_task_ctx),
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-armada-370-fix-assigned-addresses-for-every-.patch b/queue-5.10/arm-dts-armada-370-fix-assigned-addresses-for-every-.patch
new file mode 100644 (file)
index 0000000..9e080bf
--- /dev/null
@@ -0,0 +1,40 @@
+From 95d42ad838be618a2c78c910260711f2f13f06a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Aug 2022 00:30:49 +0200
+Subject: ARM: dts: armada-370: Fix assigned-addresses for every PCIe Root Port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit d9208b0fa2e803d16b28d91bf1d46b7ee9ea13c6 ]
+
+BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port
+(PCI-to-PCI bridge) should match BDF in address part in that DT node name
+as specified resource belongs to Marvell PCIe Root Port itself.
+
+Fixes: a09a0b7c6ff1 ("arm: mvebu: add PCIe Device Tree informations for Armada 370")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/armada-370.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
+index 46e6d3ed8f35..c042c416a94a 100644
+--- a/arch/arm/boot/dts/armada-370.dtsi
++++ b/arch/arm/boot/dts/armada-370.dtsi
+@@ -74,7 +74,7 @@ pcie0: pcie@1,0 {
+                       pcie2: pcie@2,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
++                              assigned-addresses = <0x82001000 0 0x80000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-armada-375-fix-assigned-addresses-for-every-.patch b/queue-5.10/arm-dts-armada-375-fix-assigned-addresses-for-every-.patch
new file mode 100644 (file)
index 0000000..270b17e
--- /dev/null
@@ -0,0 +1,40 @@
+From a61a9e4e36ad324cb7e4a60bdce1c4ff387df314 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Aug 2022 00:30:51 +0200
+Subject: ARM: dts: armada-375: Fix assigned-addresses for every PCIe Root Port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 823956d2436f70ced74c0fe8ab99facd8abfc060 ]
+
+BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port
+(PCI-to-PCI bridge) should match BDF in address part in that DT node name
+as specified resource belongs to Marvell PCIe Root Port itself.
+
+Fixes: 4de59085091f ("ARM: mvebu: add Device Tree description of the Armada 375 SoC")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/armada-375.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi
+index 9805e507c695..d117fc4ae6d9 100644
+--- a/arch/arm/boot/dts/armada-375.dtsi
++++ b/arch/arm/boot/dts/armada-375.dtsi
+@@ -582,7 +582,7 @@ pcie0: pcie@1,0 {
+                       pcie1: pcie@2,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++                              assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-armada-38x-fix-assigned-addresses-for-every-.patch b/queue-5.10/arm-dts-armada-38x-fix-assigned-addresses-for-every-.patch
new file mode 100644 (file)
index 0000000..0484bae
--- /dev/null
@@ -0,0 +1,81 @@
+From e182064808e62b0bcc47bb9a029959ce884da1c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Aug 2022 00:30:52 +0200
+Subject: ARM: dts: armada-38x: Fix assigned-addresses for every PCIe Root Port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 44f47b7a8fa4678ce4c38ea74837e4996b9df6d6 ]
+
+BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port
+(PCI-to-PCI bridge) should match BDF in address part in that DT node name
+as specified resource belongs to Marvell PCIe Root Port itself.
+
+Fixes: 0d3d96ab0059 ("ARM: mvebu: add Device Tree description of the Armada 380/385 SoCs")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/armada-380.dtsi | 4 ++--
+ arch/arm/boot/dts/armada-385.dtsi | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/boot/dts/armada-380.dtsi b/arch/arm/boot/dts/armada-380.dtsi
+index cff1269f3fbf..7146cc8f082a 100644
+--- a/arch/arm/boot/dts/armada-380.dtsi
++++ b/arch/arm/boot/dts/armada-380.dtsi
+@@ -79,7 +79,7 @@ pcie@1,0 {
+                       /* x1 port */
+                       pcie@2,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
++                              assigned-addresses = <0x82001000 0 0x40000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -98,7 +98,7 @@ pcie@2,0 {
+                       /* x1 port */
+                       pcie@3,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++                              assigned-addresses = <0x82001800 0 0x44000 0 0x2000>;
+                               reg = <0x1800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi
+index f0022d10c715..f081f7cb66e5 100644
+--- a/arch/arm/boot/dts/armada-385.dtsi
++++ b/arch/arm/boot/dts/armada-385.dtsi
+@@ -84,7 +84,7 @@ pcie1: pcie@1,0 {
+                       /* x1 port */
+                       pcie2: pcie@2,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
++                              assigned-addresses = <0x82001000 0 0x40000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -103,7 +103,7 @@ pcie2: pcie@2,0 {
+                       /* x1 port */
+                       pcie3: pcie@3,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++                              assigned-addresses = <0x82001800 0 0x44000 0 0x2000>;
+                               reg = <0x1800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -125,7 +125,7 @@ pcie3: pcie@3,0 {
+                        */
+                       pcie4: pcie@4,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++                              assigned-addresses = <0x82002000 0 0x48000 0 0x2000>;
+                               reg = <0x2000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-armada-38x-fix-compatible-string-for-gpios.patch b/queue-5.10/arm-dts-armada-38x-fix-compatible-string-for-gpios.patch
new file mode 100644 (file)
index 0000000..952cd59
--- /dev/null
@@ -0,0 +1,56 @@
+From b6ebb7d7063cfec5a86d40ed92d5774e33e91202 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 20:33:27 +0200
+Subject: ARM: dts: armada-38x: Fix compatible string for gpios
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit c4de4667f15d04ef5920bacf41e514ec7d1ef03d ]
+
+Armada 38x supports per CPU interrupts for gpios, like Armada XP. Pre-XP
+variants like Armada 370 do not support per CPU interrupts for gpios.
+
+So change compatible string for Armada 38x from "marvell,armada-370-gpio"
+which indicates pre-XP variant to "marvell,armadaxp-gpio" which indicates
+XP variant or new.
+
+Driver gpio-mvebu.c which handles both pre-XP and XP variants already
+provides support for per CPU interrupts on XP and newer variants.
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Fixes: 7cb2acb3fbae ("ARM: dts: mvebu: Add PWM properties for armada-38x")
+Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/armada-38x.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
+index df3c8d1d8f64..9343de6947b3 100644
+--- a/arch/arm/boot/dts/armada-38x.dtsi
++++ b/arch/arm/boot/dts/armada-38x.dtsi
+@@ -292,7 +292,7 @@ sata3_pins: sata-pins-3 {
+                       };
+                       gpio0: gpio@18100 {
+-                              compatible = "marvell,armada-370-gpio",
++                              compatible = "marvell,armadaxp-gpio",
+                                            "marvell,orion-gpio";
+                               reg = <0x18100 0x40>, <0x181c0 0x08>;
+                               reg-names = "gpio", "pwm";
+@@ -310,7 +310,7 @@ gpio0: gpio@18100 {
+                       };
+                       gpio1: gpio@18140 {
+-                              compatible = "marvell,armada-370-gpio",
++                              compatible = "marvell,armadaxp-gpio",
+                                            "marvell,orion-gpio";
+                               reg = <0x18140 0x40>, <0x181c8 0x08>;
+                               reg-names = "gpio", "pwm";
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-armada-39x-fix-assigned-addresses-for-every-.patch b/queue-5.10/arm-dts-armada-39x-fix-assigned-addresses-for-every-.patch
new file mode 100644 (file)
index 0000000..a37b02a
--- /dev/null
@@ -0,0 +1,58 @@
+From 4ec18b7ea74857d0cdfcc647b0096f16892d009e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Aug 2022 00:30:53 +0200
+Subject: ARM: dts: armada-39x: Fix assigned-addresses for every PCIe Root Port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 69236d2391b4d7324b11c3252921571577892e7b ]
+
+BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port
+(PCI-to-PCI bridge) should match BDF in address part in that DT node name
+as specified resource belongs to Marvell PCIe Root Port itself.
+
+Fixes: 538da83ddbea ("ARM: mvebu: add Device Tree files for Armada 39x SoC and board")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/armada-39x.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi
+index e0b7c2099831..9525e7b7f436 100644
+--- a/arch/arm/boot/dts/armada-39x.dtsi
++++ b/arch/arm/boot/dts/armada-39x.dtsi
+@@ -453,7 +453,7 @@ pcie@1,0 {
+                       /* x1 port */
+                       pcie@2,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
++                              assigned-addresses = <0x82001000 0 0x40000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -472,7 +472,7 @@ pcie@2,0 {
+                       /* x1 port */
+                       pcie@3,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++                              assigned-addresses = <0x82001800 0 0x44000 0 0x2000>;
+                               reg = <0x1800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -494,7 +494,7 @@ pcie@3,0 {
+                        */
+                       pcie@4,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++                              assigned-addresses = <0x82002000 0 0x48000 0 0x2000>;
+                               reg = <0x2000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-armada-39x-fix-compatible-string-for-gpios.patch b/queue-5.10/arm-dts-armada-39x-fix-compatible-string-for-gpios.patch
new file mode 100644 (file)
index 0000000..c0fb02c
--- /dev/null
@@ -0,0 +1,52 @@
+From c6093be28d1a38da1942431c7aea5ab937815e0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 20:33:28 +0200
+Subject: ARM: dts: armada-39x: Fix compatible string for gpios
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit d10886a4e6f85ee18d47a1066a52168461370ded ]
+
+Armada 39x supports per CPU interrupts for gpios, like Armada XP.
+
+So add compatible string "marvell,armadaxp-gpio" for Armada 39x GPIO nodes.
+
+Driver gpio-mvebu.c which handles both pre-XP and XP variants already
+provides support for per CPU interrupts on XP and newer variants.
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Fixes: d81a914fc630 ("ARM: dts: mvebu: armada-39x: add missing nodes describing GPIO's")
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/armada-39x.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi
+index 9525e7b7f436..9aad10fd3823 100644
+--- a/arch/arm/boot/dts/armada-39x.dtsi
++++ b/arch/arm/boot/dts/armada-39x.dtsi
+@@ -213,7 +213,7 @@ nand_pins: nand-pins {
+                       };
+                       gpio0: gpio@18100 {
+-                              compatible = "marvell,orion-gpio";
++                              compatible = "marvell,armadaxp-gpio", "marvell,orion-gpio";
+                               reg = <0x18100 0x40>;
+                               ngpios = <32>;
+                               gpio-controller;
+@@ -227,7 +227,7 @@ gpio0: gpio@18100 {
+                       };
+                       gpio1: gpio@18140 {
+-                              compatible = "marvell,orion-gpio";
++                              compatible = "marvell,armadaxp-gpio", "marvell,orion-gpio";
+                               reg = <0x18140 0x40>;
+                               ngpios = <28>;
+                               gpio-controller;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-armada-xp-fix-assigned-addresses-for-every-p.patch b/queue-5.10/arm-dts-armada-xp-fix-assigned-addresses-for-every-p.patch
new file mode 100644 (file)
index 0000000..0aace2b
--- /dev/null
@@ -0,0 +1,146 @@
+From c4192452ddedf5fc91e729b34a0b2f162dd50b9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Aug 2022 00:30:50 +0200
+Subject: ARM: dts: armada-xp: Fix assigned-addresses for every PCIe Root Port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit eab276787f456cbea89fabea110fe0728673d308 ]
+
+BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port
+(PCI-to-PCI bridge) should match BDF in address part in that DT node name
+as specified resource belongs to Marvell PCIe Root Port itself.
+
+Fixes: 9d8f44f02d4a ("arm: mvebu: add PCIe Device Tree informations for Armada XP")
+Fixes: 12b69a599745 ("ARM: mvebu: second PCIe unit of Armada XP mv78230 is only x1 capable")
+Fixes: 2163e61c92d9 ("ARM: mvebu: fix second and third PCIe unit of Armada XP mv78260")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/armada-xp-mv78230.dtsi |  8 ++++----
+ arch/arm/boot/dts/armada-xp-mv78260.dtsi | 16 ++++++++--------
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+index 8558bf6bb54c..d55fe162fc7f 100644
+--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+@@ -97,7 +97,7 @@ pcie1: pcie@1,0 {
+                       pcie2: pcie@2,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++                              assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -115,7 +115,7 @@ pcie2: pcie@2,0 {
+                       pcie3: pcie@3,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++                              assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
+                               reg = <0x1800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -133,7 +133,7 @@ pcie3: pcie@3,0 {
+                       pcie4: pcie@4,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
++                              assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
+                               reg = <0x2000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -151,7 +151,7 @@ pcie4: pcie@4,0 {
+                       pcie5: pcie@5,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
++                              assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+                               reg = <0x2800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+index 2d85fe8ac327..fdcc81819940 100644
+--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+@@ -112,7 +112,7 @@ pcie1: pcie@1,0 {
+                       pcie2: pcie@2,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++                              assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -130,7 +130,7 @@ pcie2: pcie@2,0 {
+                       pcie3: pcie@3,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++                              assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
+                               reg = <0x1800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -148,7 +148,7 @@ pcie3: pcie@3,0 {
+                       pcie4: pcie@4,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
++                              assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
+                               reg = <0x2000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -166,7 +166,7 @@ pcie4: pcie@4,0 {
+                       pcie5: pcie@5,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
++                              assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+                               reg = <0x2800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -184,7 +184,7 @@ pcie5: pcie@5,0 {
+                       pcie6: pcie@6,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x84000 0 0x2000>;
++                              assigned-addresses = <0x82003000 0 0x84000 0 0x2000>;
+                               reg = <0x3000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -202,7 +202,7 @@ pcie6: pcie@6,0 {
+                       pcie7: pcie@7,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x88000 0 0x2000>;
++                              assigned-addresses = <0x82003800 0 0x88000 0 0x2000>;
+                               reg = <0x3800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -220,7 +220,7 @@ pcie7: pcie@7,0 {
+                       pcie8: pcie@8,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>;
++                              assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>;
+                               reg = <0x4000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+@@ -238,7 +238,7 @@ pcie8: pcie@8,0 {
+                       pcie9: pcie@9,0 {
+                               device_type = "pci";
+-                              assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
++                              assigned-addresses = <0x82004800 0 0x42000 0 0x2000>;
+                               reg = <0x4800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-dove-fix-assigned-addresses-for-every-pcie-r.patch b/queue-5.10/arm-dts-dove-fix-assigned-addresses-for-every-pcie-r.patch
new file mode 100644 (file)
index 0000000..24ce1ba
--- /dev/null
@@ -0,0 +1,40 @@
+From 9d7bf465327f567f4fb3b36b7b09a30e4a054446 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Aug 2022 00:30:48 +0200
+Subject: ARM: dts: dove: Fix assigned-addresses for every PCIe Root Port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit dcc7d8c72b64a479b8017e4332d99179deb8802d ]
+
+BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port
+(PCI-to-PCI bridge) should match BDF in address part in that DT node name
+as specified resource belongs to Marvell PCIe Root Port itself.
+
+Fixes: 74ecaa403a74 ("ARM: dove: add PCIe controllers to SoC DT")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/dove.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
+index 89e0bdaf3a85..726d353eda68 100644
+--- a/arch/arm/boot/dts/dove.dtsi
++++ b/arch/arm/boot/dts/dove.dtsi
+@@ -129,7 +129,7 @@ pcie0: pcie@1 {
+                       pcie1: pcie@2 {
+                               device_type = "pci";
+                               status = "disabled";
+-                              assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
++                              assigned-addresses = <0x82001000 0 0x80000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               clocks = <&gate_clk 5>;
+                               marvell,pcie-port = <1>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-qcom-apq8064-fix-coresight-compatible.patch b/queue-5.10/arm-dts-qcom-apq8064-fix-coresight-compatible.patch
new file mode 100644 (file)
index 0000000..3dc903e
--- /dev/null
@@ -0,0 +1,39 @@
+From 6ddb4054f8db051e2a17da7160290ea42f73b89b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Oct 2022 21:06:57 +0200
+Subject: ARM: dts: qcom: apq8064: fix coresight compatible
+
+From: Luca Weiss <luca@z3ntu.xyz>
+
+[ Upstream commit a42b1ee868361f1cb0492f1bdaefb43e0751e468 ]
+
+There's a typo missing the arm, prefix of arm,coresight-etb10. Fix it to
+make devicetree validation happier.
+
+Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
+Fixes: 7a5c275fd821 ("ARM: dts: qcom: Add apq8064 CoreSight components")
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221013190657.48499-3-luca@z3ntu.xyz
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-apq8064.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
+index 72c4a9fc41a2..fb25ede1ce9f 100644
+--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
+@@ -1571,7 +1571,7 @@ wifi {
+               };
+               etb@1a01000 {
+-                      compatible = "coresight-etb10", "arm,primecell";
++                      compatible = "arm,coresight-etb10", "arm,primecell";
+                       reg = <0x1a01000 0x1000>;
+                       clocks = <&rpmcc RPM_QDSS_CLK>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-spear600-fix-clcd-interrupt.patch b/queue-5.10/arm-dts-spear600-fix-clcd-interrupt.patch
new file mode 100644 (file)
index 0000000..645fda2
--- /dev/null
@@ -0,0 +1,37 @@
+From bc0fe11582ccea9c4156fac4de5fdbb897c9acf5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 18:10:06 +0100
+Subject: arm: dts: spear600: Fix clcd interrupt
+
+From: Kory Maincent <kory.maincent@bootlin.com>
+
+[ Upstream commit 0336e2ce34e7a89832b6c214f924eb7bc58940be ]
+
+Interrupt 12 of the Interrupt controller belongs to the SMI controller,
+the right one for the display controller is the interrupt 13.
+
+Fixes: 8113ba917dfa ("ARM: SPEAr: DT: Update device nodes")
+Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/spear600.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
+index fd41243a0b2c..9d5a04a46b14 100644
+--- a/arch/arm/boot/dts/spear600.dtsi
++++ b/arch/arm/boot/dts/spear600.dtsi
+@@ -47,7 +47,7 @@ clcd: clcd@fc200000 {
+                       compatible = "arm,pl110", "arm,primecell";
+                       reg = <0xfc200000 0x1000>;
+                       interrupt-parent = <&vic1>;
+-                      interrupts = <12>;
++                      interrupts = <13>;
+                       status = "disabled";
+               };
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-stm32-drop-stm32mp15xc.dtsi-from-avenger96.patch b/queue-5.10/arm-dts-stm32-drop-stm32mp15xc.dtsi-from-avenger96.patch
new file mode 100644 (file)
index 0000000..cb6f2d3
--- /dev/null
@@ -0,0 +1,39 @@
+From f13ebdd514bdc2097e52fd89341d9aad6f811fc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Sep 2022 04:37:45 +0200
+Subject: ARM: dts: stm32: Drop stm32mp15xc.dtsi from Avenger96
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 3b835f1b8acef53c8882b25f40f48d7f5982c938 ]
+
+The Avenger96 is populated with STM32MP157A DHCOR SoM, drop the
+stm32mp15xc.dtsi which should only be included in DTs of devices
+which are populated with STM32MP15xC/F SoC as the stm32mp15xc.dtsi
+enables CRYP block not present in the STM32MP15xA/D SoC .
+
+Fixes: 7e76f82acd9e1 ("ARM: dts: stm32: Split Avenger96 into DHCOR SoM and Avenger96 board")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts b/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts
+index 2e3c9fbb4eb3..275167f26fd9 100644
+--- a/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts
++++ b/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts
+@@ -13,7 +13,6 @@
+ /dts-v1/;
+ #include "stm32mp157.dtsi"
+-#include "stm32mp15xc.dtsi"
+ #include "stm32mp15xx-dhcor-som.dtsi"
+ #include "stm32mp15xx-dhcor-avenger96.dtsi"
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-stm32-fix-av96-wlan-regulator-gpio-property.patch b/queue-5.10/arm-dts-stm32-fix-av96-wlan-regulator-gpio-property.patch
new file mode 100644 (file)
index 0000000..398bfa8
--- /dev/null
@@ -0,0 +1,38 @@
+From d8a4a5c962b5b93e45ab0e660407a02590ad51ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Oct 2022 12:00:57 +0200
+Subject: ARM: dts: stm32: Fix AV96 WLAN regulator gpio property
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit d5d577e3d50713ad11d98dbdaa48bb494346c26d ]
+
+The WLAN regulator uses 'gpios' property instead of 'gpio' to specify
+regulator enable GPIO. While the former is also currently handled by
+the Linux kernel regulator-fixed driver, the later is the correct one
+per DT bindings. Update the DT to use the later.
+
+Fixes: 7dd5cbba42c93 ("ARM: dts: stm32: Enable WiFi on AV96")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+index f3e0c790a4b1..723b39bb2129 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+@@ -100,7 +100,7 @@ wlan_pwr: regulator-wlan {
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+-              gpios = <&gpioz 3 GPIO_ACTIVE_HIGH>;
++              gpio = <&gpioz 3 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-turris-omnia-add-ethernet-aliases.patch b/queue-5.10/arm-dts-turris-omnia-add-ethernet-aliases.patch
new file mode 100644 (file)
index 0000000..7348d3e
--- /dev/null
@@ -0,0 +1,43 @@
+From 6ce5fd53f82262d37df0027911533f6a8d0d3667 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jul 2022 15:09:26 +0200
+Subject: ARM: dts: turris-omnia: Add ethernet aliases
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit f1f3e530c59a7e8c5f06172f4c28b945a6b4bfb8 ]
+
+This allows bootloader to correctly pass MAC addresses used by bootloader
+to individual interfaces into kernel device tree.
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Fixes: 26ca8b52d6e1 ("ARM: dts: add support for Turris Omnia")
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/armada-385-turris-omnia.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+index 92e08486ec81..c0a026ac7be8 100644
+--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts
++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+@@ -22,6 +22,12 @@ chosen {
+               stdout-path = &uart0;
+       };
++      aliases {
++              ethernet0 = &eth0;
++              ethernet1 = &eth1;
++              ethernet2 = &eth2;
++      };
++
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x40000000>; /* 1024 MB */
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-dts-turris-omnia-add-switch-port-6-node.patch b/queue-5.10/arm-dts-turris-omnia-add-switch-port-6-node.patch
new file mode 100644 (file)
index 0000000..bd07484
--- /dev/null
@@ -0,0 +1,49 @@
+From 37244cbbda163c979ea22c2afb40aadee2939114 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Aug 2022 14:21:02 +0200
+Subject: ARM: dts: turris-omnia: Add switch port 6 node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit f87db2005f73876602211af0ee156817019b6bda ]
+
+Switch port 6 is connected to eth0, so add appropriate device tree node for it.
+
+Fixes: 26ca8b52d6e1 ("ARM: dts: add support for Turris Omnia")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/armada-385-turris-omnia.dts | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+index c0a026ac7be8..320c759b4090 100644
+--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts
++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+@@ -297,7 +297,17 @@ fixed-link {
+                               };
+                       };
+-                      /* port 6 is connected to eth0 */
++                      ports@6 {
++                              reg = <6>;
++                              label = "cpu";
++                              ethernet = <&eth0>;
++                              phy-mode = "rgmii-id";
++
++                              fixed-link {
++                                      speed = <1000>;
++                                      full-duplex;
++                              };
++                      };
+               };
+       };
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm-mmp-fix-timer_read-delay.patch b/queue-5.10/arm-mmp-fix-timer_read-delay.patch
new file mode 100644 (file)
index 0000000..d20b7d8
--- /dev/null
@@ -0,0 +1,59 @@
+From f78e5d3992914f0666d327d88606f0f59e747671 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Dec 2022 16:51:17 -0800
+Subject: ARM: mmp: fix timer_read delay
+
+From: Doug Brown <doug@schmorgal.com>
+
+[ Upstream commit e348b4014c31041e13ff370669ba3348c4d385e3 ]
+
+timer_read() was using an empty 100-iteration loop to wait for the
+TMR_CVWR register to capture the latest timer counter value. The delay
+wasn't long enough. This resulted in CPU idle time being extremely
+underreported on PXA168 with CONFIG_NO_HZ_IDLE=y.
+
+Switch to the approach used in the vendor kernel, which implements the
+capture delay by reading TMR_CVWR a few times instead.
+
+Fixes: 49cbe78637eb ("[ARM] pxa: add base support for Marvell's PXA168 processor line")
+Signed-off-by: Doug Brown <doug@schmorgal.com>
+Link: https://lore.kernel.org/r/20221204005117.53452-3-doug@schmorgal.com
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-mmp/time.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
+index 41b2e8abc9e6..708816caf859 100644
+--- a/arch/arm/mach-mmp/time.c
++++ b/arch/arm/mach-mmp/time.c
+@@ -43,18 +43,21 @@
+ static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE;
+ /*
+- * FIXME: the timer needs some delay to stablize the counter capture
++ * Read the timer through the CVWR register. Delay is required after requesting
++ * a read. The CR register cannot be directly read due to metastability issues
++ * documented in the PXA168 software manual.
+  */
+ static inline uint32_t timer_read(void)
+ {
+-      int delay = 100;
++      uint32_t val;
++      int delay = 3;
+       __raw_writel(1, mmp_timer_base + TMR_CVWR(1));
+       while (delay--)
+-              cpu_relax();
++              val = __raw_readl(mmp_timer_base + TMR_CVWR(1));
+-      return __raw_readl(mmp_timer_base + TMR_CVWR(1));
++      return val;
+ }
+ static u64 notrace mmp_read_sched_clock(void)
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-armada-3720-turris-mox-add-missing-interru.patch b/queue-5.10/arm64-dts-armada-3720-turris-mox-add-missing-interru.patch
new file mode 100644 (file)
index 0000000..2d31719
--- /dev/null
@@ -0,0 +1,43 @@
+From 1e311f4b844c406bcbb952b9bdc454dc3dabf15a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Sep 2022 13:58:26 +0200
+Subject: arm64: dts: armada-3720-turris-mox: Add missing interrupt for RTC
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 21aad8ba615e9c39cee6c5d0b76726f63791926c ]
+
+MCP7940MT-I/MNY RTC has connected interrupt line to GPIO2_5.
+
+Fixes: 7109d817db2e ("arm64: dts: marvell: add DTS for Turris Mox")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+index 00e5dbf4b823..eea8d23683dc 100644
+--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
++++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+@@ -124,9 +124,12 @@ &i2c0 {
+       /delete-property/ mrvl,i2c-fast-mode;
+       status = "okay";
++      /* MCP7940MT-I/MNY RTC */
+       rtc@6f {
+               compatible = "microchip,mcp7940x";
+               reg = <0x6f>;
++              interrupt-parent = <&gpiosb>;
++              interrupts = <5 0>; /* GPIO2_5 */
+       };
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-mediatek-mt6797-fix-26m-oscillator-unit-na.patch b/queue-5.10/arm64-dts-mediatek-mt6797-fix-26m-oscillator-unit-na.patch
new file mode 100644 (file)
index 0000000..ca2eb56
--- /dev/null
@@ -0,0 +1,37 @@
+From d5cba54f0e15759b7aabf0c03b91bf2071b22a69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Oct 2022 17:22:12 +0200
+Subject: arm64: dts: mediatek: mt6797: Fix 26M oscillator unit name
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 5f535cc583759c9c60d4cc9b8d221762e2d75387 ]
+
+Update its unit name to oscillator-26m and remove the unneeded unit
+address to fix a unit_address_vs_reg warning.
+
+Fixes: 464c510f60c6 ("arm64: dts: mediatek: add mt6797 support")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221013152212.416661-9-angelogioacchino.delregno@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt6797.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
+index 15616231022a..c3677d77e0a4 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
+@@ -95,7 +95,7 @@ cpu9: cpu@201 {
+               };
+       };
+-      clk26m: oscillator@0 {
++      clk26m: oscillator-26m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <26000000>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-mediatek-pumpkin-common-fix-devicetree-war.patch b/queue-5.10/arm64-dts-mediatek-pumpkin-common-fix-devicetree-war.patch
new file mode 100644 (file)
index 0000000..4635ddb
--- /dev/null
@@ -0,0 +1,55 @@
+From 0805b68471a60a3992f3bb6b99bb15fa5b762148 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Oct 2022 17:22:11 +0200
+Subject: arm64: dts: mediatek: pumpkin-common: Fix devicetree warnings
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 509438336ce75c8b4e6ce8e8d507dc77d0783bdd ]
+
+Fix the pinctrl submodes and optee node to remove unneeded unit address,
+fixing all unit_address_vs_reg warnings.
+
+Fixes: 9983822c8cf9 ("arm64: dts: mediatek: add pumpkin board dts")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221013152212.416661-8-angelogioacchino.delregno@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
+index 99c2d6fd6304..d5059735c594 100644
+--- a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
++++ b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
+@@ -17,7 +17,7 @@ chosen {
+       };
+       firmware {
+-              optee: optee@4fd00000 {
++              optee: optee {
+                       compatible = "linaro,optee-tz";
+                       method = "smc";
+               };
+@@ -209,7 +209,7 @@ pins_cmd_dat {
+               };
+       };
+-      i2c0_pins_a: i2c0@0 {
++      i2c0_pins_a: i2c0 {
+               pins1 {
+                       pinmux = <MT8516_PIN_58_SDA0__FUNC_SDA0_0>,
+                                <MT8516_PIN_59_SCL0__FUNC_SCL0_0>;
+@@ -217,7 +217,7 @@ pins1 {
+               };
+       };
+-      i2c2_pins_a: i2c2@0 {
++      i2c2_pins_a: i2c2 {
+               pins1 {
+                       pinmux = <MT8516_PIN_60_SDA2__FUNC_SDA2_0>,
+                                <MT8516_PIN_61_SCL2__FUNC_SCL2_0>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-mt2712-evb-fix-usb-vbus-regulators-unit-na.patch b/queue-5.10/arm64-dts-mt2712-evb-fix-usb-vbus-regulators-unit-na.patch
new file mode 100644 (file)
index 0000000..359fc64
--- /dev/null
@@ -0,0 +1,64 @@
+From 683eb6e56f3f668e4c0d92bc7c4757e6c5f69d54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Oct 2022 17:22:10 +0200
+Subject: arm64: dts: mt2712-evb: Fix usb vbus regulators unit names
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit ec1ae39a8d25cfb067b5459fac7c5b7b9bce6f6a ]
+
+Update the names to regulator-usb-p{0-3}-vbus to fix unit_address_vs_reg
+warnings for those.
+
+Fixes: 1724f4cc5133 ("arm64: dts: Add USB3 related nodes for MT2712")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221013152212.416661-7-angelogioacchino.delregno@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt2712-evb.dts | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+index b78d441616b1..9d20cabf4f69 100644
+--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+@@ -50,7 +50,7 @@ extcon_usb1: extcon_iddig1 {
+               id-gpio = <&pio 14 GPIO_ACTIVE_HIGH>;
+       };
+-      usb_p0_vbus: regulator@2 {
++      usb_p0_vbus: regulator-usb-p0-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "p0_vbus";
+               regulator-min-microvolt = <5000000>;
+@@ -59,7 +59,7 @@ usb_p0_vbus: regulator@2 {
+               enable-active-high;
+       };
+-      usb_p1_vbus: regulator@3 {
++      usb_p1_vbus: regulator-usb-p1-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "p1_vbus";
+               regulator-min-microvolt = <5000000>;
+@@ -68,7 +68,7 @@ usb_p1_vbus: regulator@3 {
+               enable-active-high;
+       };
+-      usb_p2_vbus: regulator@4 {
++      usb_p2_vbus: regulator-usb-p2-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "p2_vbus";
+               regulator-min-microvolt = <5000000>;
+@@ -77,7 +77,7 @@ usb_p2_vbus: regulator@4 {
+               enable-active-high;
+       };
+-      usb_p3_vbus: regulator@5 {
++      usb_p3_vbus: regulator-usb-p3-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "p3_vbus";
+               regulator-min-microvolt = <5000000>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-mt2712-evb-fix-vproc-fixed-regulators-unit.patch b/queue-5.10/arm64-dts-mt2712-evb-fix-vproc-fixed-regulators-unit.patch
new file mode 100644 (file)
index 0000000..fe4ae9c
--- /dev/null
@@ -0,0 +1,45 @@
+From fbd4932a0ebbe28da5d5ca04de73b3a9bbf5572d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Oct 2022 17:22:09 +0200
+Subject: arm64: dts: mt2712-evb: Fix vproc fixed regulators unit names
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 377063156893bf6c088309ac799fe5c6dce2822d ]
+
+Update the names to regulator-vproc-buck{0,1} to fix unit_addres_vs_reg
+warnings for those.
+
+Fixes: f75dd8bdd344 ("arm64: dts: mediatek: add mt2712 cpufreq related device nodes")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221013152212.416661-6-angelogioacchino.delregno@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt2712-evb.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+index 7d369fdd3117..b78d441616b1 100644
+--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+@@ -26,14 +26,14 @@ chosen {
+               stdout-path = "serial0:921600n8";
+       };
+-      cpus_fixed_vproc0: fixedregulator@0 {
++      cpus_fixed_vproc0: regulator-vproc-buck0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vproc_buck0";
+               regulator-min-microvolt = <1000000>;
+               regulator-max-microvolt = <1000000>;
+       };
+-      cpus_fixed_vproc1: fixedregulator@1 {
++      cpus_fixed_vproc1: regulator-vproc-buck1 {
+               compatible = "regulator-fixed";
+               regulator-name = "vproc_buck1";
+               regulator-min-microvolt = <1000000>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-mt2712e-fix-unit-address-for-pinctrl-node.patch b/queue-5.10/arm64-dts-mt2712e-fix-unit-address-for-pinctrl-node.patch
new file mode 100644 (file)
index 0000000..3e27394
--- /dev/null
@@ -0,0 +1,42 @@
+From 601eb5ee2362902560e8a4a1be85f73d1106b924 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Oct 2022 17:22:08 +0200
+Subject: arm64: dts: mt2712e: Fix unit address for pinctrl node
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 1d4516f53a611b362db7ba7a8889923d469f57e1 ]
+
+The unit address for the pinctrl node is (0x)1000b000 and not
+(0x)10005000, which is the syscfg_pctl_a address instead.
+
+This fixes the following warning:
+arch/arm64/boot/dts/mediatek/mt2712e.dtsi:264.40-267.4: Warning
+(unique_unit_address): /syscfg_pctl_a@10005000: duplicate
+unit-address (also used in node /pinctrl@10005000)
+
+Fixes: f0c64340b748 ("arm64: dts: mt2712: add pintcrl device node.")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221013152212.416661-5-angelogioacchino.delregno@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+index e0b26cd67eb3..cc3d1c99517d 100644
+--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+@@ -266,7 +266,7 @@ syscfg_pctl_a: syscfg_pctl_a@10005000 {
+               reg = <0 0x10005000 0 0x1000>;
+       };
+-      pio: pinctrl@10005000 {
++      pio: pinctrl@1000b000 {
+               compatible = "mediatek,mt2712-pinctrl";
+               reg = <0 0x1000b000 0 0x1000>;
+               mediatek,pctl-regmap = <&syscfg_pctl_a>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-mt2712e-fix-unit_address_vs_reg-warning-fo.patch b/queue-5.10/arm64-dts-mt2712e-fix-unit_address_vs_reg-warning-fo.patch
new file mode 100644 (file)
index 0000000..a118c5c
--- /dev/null
@@ -0,0 +1,110 @@
+From 48c319a9abc8515f49192b0e8bc5bd79f1827e20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Oct 2022 17:22:07 +0200
+Subject: arm64: dts: mt2712e: Fix unit_address_vs_reg warning for oscillators
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit e4495a0a8b3d84816c9a46edf3ce060bbf267475 ]
+
+Rename the fixed-clock oscillators to remove the unit address.
+
+This solves unit_address_vs_reg warnings.
+
+Fixes: 5d4839709c8e ("arm64: dts: mt2712: Add clock controller device nodes")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221013152212.416661-4-angelogioacchino.delregno@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+index db17d0a4ed57..e0b26cd67eb3 100644
+--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+@@ -160,70 +160,70 @@ sys_clk: dummyclk {
+               #clock-cells = <0>;
+       };
+-      clk26m: oscillator@0 {
++      clk26m: oscillator-26m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <26000000>;
+               clock-output-names = "clk26m";
+       };
+-      clk32k: oscillator@1 {
++      clk32k: oscillator-32k {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               clock-output-names = "clk32k";
+       };
+-      clkfpc: oscillator@2 {
++      clkfpc: oscillator-50m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <50000000>;
+               clock-output-names = "clkfpc";
+       };
+-      clkaud_ext_i_0: oscillator@3 {
++      clkaud_ext_i_0: oscillator-aud0 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <6500000>;
+               clock-output-names = "clkaud_ext_i_0";
+       };
+-      clkaud_ext_i_1: oscillator@4 {
++      clkaud_ext_i_1: oscillator-aud1 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <196608000>;
+               clock-output-names = "clkaud_ext_i_1";
+       };
+-      clkaud_ext_i_2: oscillator@5 {
++      clkaud_ext_i_2: oscillator-aud2 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <180633600>;
+               clock-output-names = "clkaud_ext_i_2";
+       };
+-      clki2si0_mck_i: oscillator@6 {
++      clki2si0_mck_i: oscillator-i2s0 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <30000000>;
+               clock-output-names = "clki2si0_mck_i";
+       };
+-      clki2si1_mck_i: oscillator@7 {
++      clki2si1_mck_i: oscillator-i2s1 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <30000000>;
+               clock-output-names = "clki2si1_mck_i";
+       };
+-      clki2si2_mck_i: oscillator@8 {
++      clki2si2_mck_i: oscillator-i2s2 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <30000000>;
+               clock-output-names = "clki2si2_mck_i";
+       };
+-      clktdmin_mclk_i: oscillator@9 {
++      clktdmin_mclk_i: oscillator-mclk {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <30000000>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-qcom-ipq6018-cp01-c1-use-blspi1-pins.patch b/queue-5.10/arm64-dts-qcom-ipq6018-cp01-c1-use-blspi1-pins.patch
new file mode 100644 (file)
index 0000000..009a719
--- /dev/null
@@ -0,0 +1,40 @@
+From edca0888b7ca346668cc730773a46e43a3e4540c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Oct 2022 14:46:26 +0200
+Subject: arm64: dts: qcom: ipq6018-cp01-c1: use BLSPI1 pins
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 4871d3c38893c8a585e3e96364b7fb91cda8322e ]
+
+When BLSPI1 (originally SPI0, later renamed in commit f82c48d46852
+("arm64: dts: qcom: ipq6018: correct QUP peripheral labels")) was added,
+the device node lacked respective pin configuration assignment.
+
+Fixes: 5bf635621245 ("arm64: dts: ipq6018: Add a few device nodes")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Bjorn Andersson <andersson@kernel.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221006124659.217540-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
+index e8eaa958c199..b867506bc7e1 100644
+--- a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
++++ b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
+@@ -37,6 +37,8 @@ &i2c_1 {
+ &spi_0 {
+       cs-select = <0>;
++      pinctrl-0 = <&spi_0_pins>;
++      pinctrl-names = "default";
+       status = "okay";
+       m25p80@0 {
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-qcom-msm8916-drop-mss-fallback-compatible.patch b/queue-5.10/arm64-dts-qcom-msm8916-drop-mss-fallback-compatible.patch
new file mode 100644 (file)
index 0000000..66b8882
--- /dev/null
@@ -0,0 +1,52 @@
+From e211f2bf793345daad0de5940f60a77413223c29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 16:03:40 +0200
+Subject: arm64: dts: qcom: msm8916: Drop MSS fallback compatible
+
+From: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+
+[ Upstream commit ff02ac621634e82c0c34d02a79d402ae700cdfd0 ]
+
+MSM8916 was originally using the "qcom,q6v5-pil" compatible for the
+MSS remoteproc. Later it was decided to use SoC-specific compatibles
+instead, so "qcom,msm8916-mss-pil" is now the preferred compatible.
+
+Commit 60a05ed059a0 ("arm64: dts: qcom: msm8916: Add MSM8916-specific
+compatibles to SCM/MSS") updated the MSM8916 device tree to make use of
+the new compatible but still kept the old "qcom,q6v5-pil" as fallback.
+
+This is inconsistent with other SoCs and conflicts with the description
+in the binding documentation (which says that only one compatible should
+be present). Also, it has no functional advantage since older kernels
+could not handle this DT anyway (e.g. "power-domains" in the MSS node is
+only supported by kernels that also support "qcom,msm8916-mss-pil").
+
+Make this consistent with other SoCs by using only the
+"qcom,msm8916-mss-pil" compatible.
+
+Fixes: 60a05ed059a0 ("arm64: dts: qcom: msm8916: Add MSM8916-specific compatibles to SCM/MSS")
+Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20220718140344.1831731-2-stephan.gerhold@kernkonzept.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index 291276a38d7c..c32e4a3833f2 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1249,7 +1249,7 @@ spmi_bus: spmi@200f000 {
+               };
+               mpss: remoteproc@4080000 {
+-                      compatible = "qcom,msm8916-mss-pil", "qcom,q6v5-pil";
++                      compatible = "qcom,msm8916-mss-pil";
+                       reg = <0x04080000 0x100>,
+                             <0x04020000 0x040>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-qcom-msm8996-fix-gpu-opp-table.patch b/queue-5.10/arm64-dts-qcom-msm8996-fix-gpu-opp-table.patch
new file mode 100644 (file)
index 0000000..1e36d16
--- /dev/null
@@ -0,0 +1,52 @@
+From 5383ff95c6670fc36f125862df46244e6f264e87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Jul 2022 17:04:20 +0300
+Subject: arm64: dts: qcom: msm8996: fix GPU OPP table
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 0d440d811e6e2f37093e54db55bc27fe66678170 ]
+
+Fix Adreno OPP table according to the msm-3.18. Enable 624 MHz for the
+speed bin 3 and 560 MHz for bins 2 and 3.
+
+Fixes: 69cc3114ab0f ("arm64: dts: Add Adreno GPU definitions")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20220724140421.1933004-7-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8996.dtsi | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+index ef5d03a15069..bc140269e4cc 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -651,17 +651,17 @@ gpu_opp_table: opp-table {
+                               compatible  ="operating-points-v2";
+                               /*
+-                               * 624Mhz and 560Mhz are only available on speed
+-                               * bin (1 << 0). All the rest are available on
+-                               * all bins of the hardware
++                               * 624Mhz is only available on speed bins 0 and 3.
++                               * 560Mhz is only available on speed bins 0, 2 and 3.
++                               * All the rest are available on all bins of the hardware.
+                                */
+                               opp-624000000 {
+                                       opp-hz = /bits/ 64 <624000000>;
+-                                      opp-supported-hw = <0x01>;
++                                      opp-supported-hw = <0x09>;
+                               };
+                               opp-560000000 {
+                                       opp-hz = /bits/ 64 <560000000>;
+-                                      opp-supported-hw = <0x01>;
++                                      opp-supported-hw = <0x0d>;
+                               };
+                               opp-510000000 {
+                                       opp-hz = /bits/ 64 <510000000>;
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-qcom-sdm630-fix-uart1-pin-bias.patch b/queue-5.10/arm64-dts-qcom-sdm630-fix-uart1-pin-bias.patch
new file mode 100644 (file)
index 0000000..d043041
--- /dev/null
@@ -0,0 +1,38 @@
+From f82045596fbb7b15bc5e762b1a7852a7ec4a42fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 07:44:12 -0400
+Subject: arm64: dts: qcom: sdm630: fix UART1 pin bias
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 780f836fe071a9e8703fe6a05ae00129acf83391 ]
+
+There is no "bias-no-pull" property.  Assume intentions were disabling
+bias.
+
+Fixes: b190fb010664 ("arm64: dts: qcom: sdm630: Add sdm630 dts file")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221010114417.29859-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+index f87054575ce7..79d260c2b3c3 100644
+--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+@@ -593,7 +593,7 @@ rx-cts-rts {
+                                       pins = "gpio17", "gpio18", "gpio19";
+                                       function = "gpio";
+                                       drive-strength = <2>;
+-                                      bias-no-pull;
++                                      bias-disable;
+                               };
+                       };
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-qcom-sdm845-cheza-fix-ap-suspend-pin-bias.patch b/queue-5.10/arm64-dts-qcom-sdm845-cheza-fix-ap-suspend-pin-bias.patch
new file mode 100644 (file)
index 0000000..be92ca6
--- /dev/null
@@ -0,0 +1,47 @@
+From 91fef4ae7608029d5b0f772b02dbede58bdd9d33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 07:44:14 -0400
+Subject: arm64: dts: qcom: sdm845-cheza: fix AP suspend pin bias
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 9bce41fab14da8f21027dc9847535ef5e22cbe8b ]
+
+There is no "bias-no-pull" property.  Assume intentions were disabling
+bias.
+
+Fixes: 79e7739f7b87 ("arm64: dts: qcom: sdm845-cheza: add initial cheza dt")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221010114417.29859-3-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
+index 64fc1bfd66fa..26f6f193bd1b 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
+@@ -1292,7 +1292,7 @@ ap_suspend_l_assert: ap_suspend_l_assert {
+               config {
+                       pins = "gpio126";
+                       function = "gpio";
+-                      bias-no-pull;
++                      bias-disable;
+                       drive-strength = <2>;
+                       output-low;
+               };
+@@ -1302,7 +1302,7 @@ ap_suspend_l_deassert: ap_suspend_l_deassert {
+               config {
+                       pins = "gpio126";
+                       function = "gpio";
+-                      bias-no-pull;
++                      bias-disable;
+                       drive-strength = <2>;
+                       output-high;
+               };
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-ti-k3-am65-main-drop-dma-coherent-in-crypt.patch b/queue-5.10/arm64-dts-ti-k3-am65-main-drop-dma-coherent-in-crypt.patch
new file mode 100644 (file)
index 0000000..aadc067
--- /dev/null
@@ -0,0 +1,36 @@
+From 1a0a471ddfb649468e6acce2cee17fa7a329d3ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Oct 2022 20:55:18 +0530
+Subject: arm64: dts: ti: k3-am65-main: Drop dma-coherent in crypto node
+
+From: Jayesh Choudhary <j-choudhary@ti.com>
+
+[ Upstream commit b86833ab3653dbb0dc453eec4eef8615e63de4e2 ]
+
+crypto driver itself is not dma-coherent. So drop it.
+
+Fixes: b366b2409c97 ("arm64: dts: ti: k3-am6: Add crypto accelarator node")
+Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com>
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Reviewed-by: Manorit Chawdhry <m-chawdhry@ti.com>
+Link: https://lore.kernel.org/r/20221031152520.355653-2-j-choudhary@ti.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+index d04189771c77..4265f627ca16 100644
+--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+@@ -127,7 +127,6 @@ crypto: crypto@4e00000 {
+               dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>,
+                               <&main_udmap 0x4001>;
+               dma-names = "tx", "rx1", "rx2";
+-              dma-coherent;
+               rng: rng@4e10000 {
+                       compatible = "inside-secure,safexcel-eip76";
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-dts-ti-k3-j721e-main-drop-dma-coherent-in-cryp.patch b/queue-5.10/arm64-dts-ti-k3-j721e-main-drop-dma-coherent-in-cryp.patch
new file mode 100644 (file)
index 0000000..fff6b4a
--- /dev/null
@@ -0,0 +1,36 @@
+From e0fcfcfb0d0cb3c6a58c68f0f19123df4f09f702 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Oct 2022 20:55:19 +0530
+Subject: arm64: dts: ti: k3-j721e-main: Drop dma-coherent in crypto node
+
+From: Jayesh Choudhary <j-choudhary@ti.com>
+
+[ Upstream commit 26c5012403f3f1fd3bf8f7d3389ee539ae5cc162 ]
+
+crypto driver itself is not dma-coherent. So drop it.
+
+Fixes: 8ebcaaae8017 ("arm64: dts: ti: k3-j721e-main: Add crypto accelerator node")
+Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com>
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Reviewed-by: Manorit Chawdhry <m-chawdhry@ti.com>
+Link: https://lore.kernel.org/r/20221031152520.355653-3-j-choudhary@ti.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+index 0350ddfe2c72..691d73f0f1e0 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+@@ -367,7 +367,6 @@ main_crypto: crypto@4e00000 {
+               dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>,
+                               <&main_udmap 0x4001>;
+               dma-names = "tx", "rx1", "rx2";
+-              dma-coherent;
+               rng: rng@4e10000 {
+                       compatible = "inside-secure,safexcel-eip76";
+-- 
+2.35.1
+
diff --git a/queue-5.10/arm64-make-is_ttbrx_addr-noinstr-safe.patch b/queue-5.10/arm64-make-is_ttbrx_addr-noinstr-safe.patch
new file mode 100644 (file)
index 0000000..8f91a86
--- /dev/null
@@ -0,0 +1,52 @@
+From 54045e423b9a389b6b5b277cb346761fcc34cd20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 14:40:42 +0000
+Subject: arm64: make is_ttbrX_addr() noinstr-safe
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit d8c1d798a2e5091128c391c6dadcc9be334af3f5 ]
+
+We use is_ttbr0_addr() in noinstr code, but as it's only marked as
+inline, it's theoretically possible for the compiler to place it
+out-of-line and instrument it, which would be problematic.
+
+Mark is_ttbr0_addr() as __always_inline such that that can safely be
+used from noinstr code. For consistency, do the same to is_ttbr1_addr().
+Note that while is_ttbr1_addr() calls arch_kasan_reset_tag(), this is a
+macro (and its callees are either macros or __always_inline), so there
+is not a risk of transient instrumentation.
+
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20221114144042.3001140-1-mark.rutland@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/processor.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
+index 7c546c3487c9..c628d8e3a403 100644
+--- a/arch/arm64/include/asm/processor.h
++++ b/arch/arm64/include/asm/processor.h
+@@ -230,13 +230,13 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
+ }
+ #endif
+-static inline bool is_ttbr0_addr(unsigned long addr)
++static __always_inline bool is_ttbr0_addr(unsigned long addr)
+ {
+       /* entry assembly clears tags for TTBR0 addrs */
+       return addr < TASK_SIZE;
+ }
+-static inline bool is_ttbr1_addr(unsigned long addr)
++static __always_inline bool is_ttbr1_addr(unsigned long addr)
+ {
+       /* TTBR1 addresses may have a tag if KASAN_SW_TAGS is in use */
+       return arch_kasan_reset_tag(addr) >= PAGE_OFFSET;
+-- 
+2.35.1
+
diff --git a/queue-5.10/asoc-codecs-rt298-add-quirk-for-kbl-r-rvp-platform.patch b/queue-5.10/asoc-codecs-rt298-add-quirk-for-kbl-r-rvp-platform.patch
new file mode 100644 (file)
index 0000000..9185fa9
--- /dev/null
@@ -0,0 +1,45 @@
+From 9f6538a721c015d97c1a1289ee0bbd8ccb15cedf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 14:19:43 +0200
+Subject: ASoC: codecs: rt298: Add quirk for KBL-R RVP platform
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+
+[ Upstream commit 953dbd1cef18ce9ac0d69c1bd735b929fe52a17e ]
+
+KBL-R RVP platforms also use combojack, so we need to enable that
+configuration for them.
+
+Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Link: https://lore.kernel.org/r/20221010121955.718168-4-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt298.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c
+index dc0273a5a11f..1ca06213e3a3 100644
+--- a/sound/soc/codecs/rt298.c
++++ b/sound/soc/codecs/rt298.c
+@@ -1168,6 +1168,13 @@ static const struct dmi_system_id force_combo_jack_table[] = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Geminilake")
+               }
+       },
++      {
++              .ident = "Intel Kabylake R RVP",
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform")
++              }
++      },
+       { }
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.10/asoc-dt-bindings-wcd9335-fix-reset-line-polarity-in-.patch b/queue-5.10/asoc-dt-bindings-wcd9335-fix-reset-line-polarity-in-.patch
new file mode 100644 (file)
index 0000000..6ae8cbe
--- /dev/null
@@ -0,0 +1,39 @@
+From b1469db481774f1405441b572582e59849686850 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 00:46:48 -0700
+Subject: ASoC: dt-bindings: wcd9335: fix reset line polarity in example
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+[ Upstream commit 34cb111f8a7b98b5fec809dd194003bca20ef1b2 ]
+
+When resetting the block, the reset line is being driven low and then
+high, which means that the line in DTS should be annotated as "active
+low".
+
+Fixes: 1877c9fda1b7 ("ASoC: dt-bindings: add dt bindings for wcd9335 audio codec")
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20221027074652.1044235-2-dmitry.torokhov@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/sound/qcom,wcd9335.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt b/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
+index 5d6ea66a863f..1f75feec3dec 100644
+--- a/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
++++ b/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
+@@ -109,7 +109,7 @@ audio-codec@1{
+       reg  = <1 0>;
+       interrupts = <&msmgpio 54 IRQ_TYPE_LEVEL_HIGH>;
+       interrupt-names = "intr2"
+-      reset-gpios = <&msmgpio 64 0>;
++      reset-gpios = <&msmgpio 64 GPIO_ACTIVE_LOW>;
+       slim-ifc-dev  = <&wc9335_ifd>;
+       clock-names = "mclk", "native";
+       clocks = <&rpmcc RPM_SMD_DIV_CLK1>,
+-- 
+2.35.1
+
diff --git a/queue-5.10/asoc-mediatek-mt8173-enable-irq-when-pdata-is-ready.patch b/queue-5.10/asoc-mediatek-mt8173-enable-irq-when-pdata-is-ready.patch
new file mode 100644 (file)
index 0000000..96107af
--- /dev/null
@@ -0,0 +1,71 @@
+From 9ab1373cc34272e6bd247ca00b9d5a72eb9563bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 11:49:16 +0100
+Subject: ASoC: mediatek: mt8173: Enable IRQ when pdata is ready
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+[ Upstream commit 4cbb264d4e9136acab2c8fd39e39ab1b1402b84b ]
+
+If the device does not come straight from reset, we might receive an IRQ
+before we are ready to handle it.
+
+Fixes:
+
+[    2.334737] Unable to handle kernel read from unreadable memory at virtual address 00000000000001e4
+[    2.522601] Call trace:
+[    2.525040]  regmap_read+0x1c/0x80
+[    2.528434]  mt8173_afe_irq_handler+0x40/0xf0
+...
+[    2.598921]  start_kernel+0x338/0x42c
+
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Fixes: ee0bcaff109f ("ASoC: mediatek: Add AFE platform driver")
+Link: https://lore.kernel.org/r/20221128-mt8173-afe-v1-0-70728221628f@chromium.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+index a8c7617978a6..619d6733091c 100644
+--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
++++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+@@ -1072,16 +1072,6 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
+       afe->dev = &pdev->dev;
+-      irq_id = platform_get_irq(pdev, 0);
+-      if (irq_id <= 0)
+-              return irq_id < 0 ? irq_id : -ENXIO;
+-      ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler,
+-                             0, "Afe_ISR_Handle", (void *)afe);
+-      if (ret) {
+-              dev_err(afe->dev, "could not request_irq\n");
+-              return ret;
+-      }
+-
+       afe->base_addr = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(afe->base_addr))
+               return PTR_ERR(afe->base_addr);
+@@ -1187,6 +1177,16 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
+       if (ret)
+               goto err_cleanup_components;
++      irq_id = platform_get_irq(pdev, 0);
++      if (irq_id <= 0)
++              return irq_id < 0 ? irq_id : -ENXIO;
++      ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler,
++                             0, "Afe_ISR_Handle", (void *)afe);
++      if (ret) {
++              dev_err(afe->dev, "could not request_irq\n");
++              goto err_pm_disable;
++      }
++
+       dev_info(&pdev->dev, "MT8173 AFE driver initialized.\n");
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/asoc-mediatek-mt8173-fix-debugfs-registration-for-co.patch b/queue-5.10/asoc-mediatek-mt8173-fix-debugfs-registration-for-co.patch
new file mode 100644 (file)
index 0000000..64cf497
--- /dev/null
@@ -0,0 +1,117 @@
+From 454578a30afdd79ebf4ee5a664a4ed8a9f6798c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Nov 2021 17:11:08 +0100
+Subject: ASoC: mediatek: mt8173: Fix debugfs registration for components
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 8c32984bc7da29828260ac514d5d4967f7e8f62d ]
+
+When registering the mt8173-afe-pcm driver, we are also adding two
+components: one is for the PCM DAIs and one is for the HDMI DAIs, but
+when debugfs is enabled, we're getting the following issue:
+
+[   17.279176] debugfs: Directory '11220000.audio-controller' with parent 'mtk-rt5650' already present!
+[   17.288345] debugfs: Directory '11220000.audio-controller' with parent 'mtk-rt5650' already present!
+
+To overcome to that without any potentially big rewrite of this driver,
+similarly to what was done in mt8195-afe-pcm, add a debugfs_prefix to
+the components before actually adding them.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20211111161108.502344-1-angelogioacchino.delregno@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 4cbb264d4e91 ("ASoC: mediatek: mt8173: Enable IRQ when pdata is ready")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 51 ++++++++++++++++++----
+ 1 file changed, 43 insertions(+), 8 deletions(-)
+
+diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+index 7e7bda70d12e..a8c7617978a6 100644
+--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
++++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+@@ -1054,6 +1054,7 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
+       int irq_id;
+       struct mtk_base_afe *afe;
+       struct mt8173_afe_private *afe_priv;
++      struct snd_soc_component *comp_pcm, *comp_hdmi;
+       ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
+       if (ret)
+@@ -1142,23 +1143,55 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
+       if (ret)
+               goto err_pm_disable;
+-      ret = devm_snd_soc_register_component(&pdev->dev,
+-                                       &mt8173_afe_pcm_dai_component,
+-                                       mt8173_afe_pcm_dais,
+-                                       ARRAY_SIZE(mt8173_afe_pcm_dais));
++      comp_pcm = devm_kzalloc(&pdev->dev, sizeof(*comp_pcm), GFP_KERNEL);
++      if (!comp_pcm) {
++              ret = -ENOMEM;
++              goto err_pm_disable;
++      }
++
++      ret = snd_soc_component_initialize(comp_pcm,
++                                         &mt8173_afe_pcm_dai_component,
++                                         &pdev->dev);
+       if (ret)
+               goto err_pm_disable;
+-      ret = devm_snd_soc_register_component(&pdev->dev,
+-                                       &mt8173_afe_hdmi_dai_component,
+-                                       mt8173_afe_hdmi_dais,
+-                                       ARRAY_SIZE(mt8173_afe_hdmi_dais));
++#ifdef CONFIG_DEBUG_FS
++      comp_pcm->debugfs_prefix = "pcm";
++#endif
++
++      ret = snd_soc_add_component(comp_pcm,
++                                  mt8173_afe_pcm_dais,
++                                  ARRAY_SIZE(mt8173_afe_pcm_dais));
++      if (ret)
++              goto err_pm_disable;
++
++      comp_hdmi = devm_kzalloc(&pdev->dev, sizeof(*comp_hdmi), GFP_KERNEL);
++      if (!comp_hdmi) {
++              ret = -ENOMEM;
++              goto err_pm_disable;
++      }
++
++      ret = snd_soc_component_initialize(comp_hdmi,
++                                         &mt8173_afe_hdmi_dai_component,
++                                         &pdev->dev);
+       if (ret)
+               goto err_pm_disable;
++#ifdef CONFIG_DEBUG_FS
++      comp_hdmi->debugfs_prefix = "hdmi";
++#endif
++
++      ret = snd_soc_add_component(comp_hdmi,
++                                  mt8173_afe_hdmi_dais,
++                                  ARRAY_SIZE(mt8173_afe_hdmi_dais));
++      if (ret)
++              goto err_cleanup_components;
++
+       dev_info(&pdev->dev, "MT8173 AFE driver initialized.\n");
+       return 0;
++err_cleanup_components:
++      snd_soc_unregister_component(&pdev->dev);
+ err_pm_disable:
+       pm_runtime_disable(&pdev->dev);
+       return ret;
+@@ -1166,6 +1199,8 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
+ static int mt8173_afe_pcm_dev_remove(struct platform_device *pdev)
+ {
++      snd_soc_unregister_component(&pdev->dev);
++
+       pm_runtime_disable(&pdev->dev);
+       if (!pm_runtime_status_suspended(&pdev->dev))
+               mt8173_afe_runtime_suspend(&pdev->dev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/asoc-mediatek-mtk-btcvsd-add-checks-for-write-and-re.patch b/queue-5.10/asoc-mediatek-mtk-btcvsd-add-checks-for-write-and-re.patch
new file mode 100644 (file)
index 0000000..9a23ad2
--- /dev/null
@@ -0,0 +1,43 @@
+From 8f843e27a4dfb0369b975d1d958935ae0d13b83d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 11:07:50 +0800
+Subject: ASoC: mediatek: mtk-btcvsd: Add checks for write and read of
+ mtk_btcvsd_snd
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit d067b3378a78c9c3048ac535e31c171b6f5b5846 ]
+
+As the mtk_btcvsd_snd_write and mtk_btcvsd_snd_read may return error,
+it should be better to catch the exception.
+
+Fixes: 4bd8597dc36c ("ASoC: mediatek: add btcvsd driver")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20221116030750.40500-1-jiasheng@iscas.ac.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/common/mtk-btcvsd.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/mediatek/common/mtk-btcvsd.c b/sound/soc/mediatek/common/mtk-btcvsd.c
+index 86e982e3209e..e1f57b0dedd0 100644
+--- a/sound/soc/mediatek/common/mtk-btcvsd.c
++++ b/sound/soc/mediatek/common/mtk-btcvsd.c
+@@ -1038,11 +1038,9 @@ static int mtk_pcm_btcvsd_copy(struct snd_soc_component *component,
+       struct mtk_btcvsd_snd *bt = snd_soc_component_get_drvdata(component);
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+-              mtk_btcvsd_snd_write(bt, buf, count);
++              return mtk_btcvsd_snd_write(bt, buf, count);
+       else
+-              mtk_btcvsd_snd_read(bt, buf, count);
+-
+-      return 0;
++              return mtk_btcvsd_snd_read(bt, buf, count);
+ }
+ /* kcontrol */
+-- 
+2.35.1
+
diff --git a/queue-5.10/asoc-pcm512x-fix-pm-disable-depth-imbalance-in-pcm51.patch b/queue-5.10/asoc-pcm512x-fix-pm-disable-depth-imbalance-in-pcm51.patch
new file mode 100644 (file)
index 0000000..f50c1dc
--- /dev/null
@@ -0,0 +1,64 @@
+From b5b742564e417ad159afab328c3d82f16483fa1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Sep 2022 00:04:02 +0800
+Subject: ASoC: pcm512x: Fix PM disable depth imbalance in pcm512x_probe
+
+From: Zhang Qilong <zhangqilong3@huawei.com>
+
+[ Upstream commit 97b801be6f8e53676b9f2b105f54e35c745c1b22 ]
+
+The pm_runtime_enable will increase power disable depth. Thus
+a pairing decrement is needed on the error handling path to
+keep it balanced according to context. We fix it by going to
+err_pm instead of err_clk.
+
+Fixes:f086ba9d5389c ("ASoC: pcm512x: Support mastering BCLK/LRCLK using the PLL")
+
+Signed-off-by: Zhang Qilong <zhangqilong3@huawei.com>
+Link: https://lore.kernel.org/r/20220928160402.126140-1-zhangqilong3@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/pcm512x.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
+index 8153d3d01654..3677e9029f91 100644
+--- a/sound/soc/codecs/pcm512x.c
++++ b/sound/soc/codecs/pcm512x.c
+@@ -1599,7 +1599,7 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
+                       if (val > 6) {
+                               dev_err(dev, "Invalid pll-in\n");
+                               ret = -EINVAL;
+-                              goto err_clk;
++                              goto err_pm;
+                       }
+                       pcm512x->pll_in = val;
+               }
+@@ -1608,7 +1608,7 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
+                       if (val > 6) {
+                               dev_err(dev, "Invalid pll-out\n");
+                               ret = -EINVAL;
+-                              goto err_clk;
++                              goto err_pm;
+                       }
+                       pcm512x->pll_out = val;
+               }
+@@ -1617,12 +1617,12 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
+                       dev_err(dev,
+                               "Error: both pll-in and pll-out, or none\n");
+                       ret = -EINVAL;
+-                      goto err_clk;
++                      goto err_pm;
+               }
+               if (pcm512x->pll_in && pcm512x->pll_in == pcm512x->pll_out) {
+                       dev_err(dev, "Error: pll-in == pll-out\n");
+                       ret = -EINVAL;
+-                      goto err_clk;
++                      goto err_pm;
+               }
+       }
+ #endif
+-- 
+2.35.1
+
diff --git a/queue-5.10/asoc-pxa-fix-null-pointer-dereference-in-filter.patch b/queue-5.10/asoc-pxa-fix-null-pointer-dereference-in-filter.patch
new file mode 100644 (file)
index 0000000..f33df7b
--- /dev/null
@@ -0,0 +1,37 @@
+From 35f2d6803acc79af8e6b4c33aef02a2d49554866 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 16:56:29 +0800
+Subject: ASoC: pxa: fix null-pointer dereference in filter()
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit ec7bf231aaa1bdbcb69d23bc50c753c80fb22429 ]
+
+kasprintf() would return NULL pointer when kmalloc() fail to allocate.
+Need to check the return pointer before calling strcmp().
+
+Fixes: 7a824e214e25 ("ASoC: mmp: add audio dma support")
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Link: https://lore.kernel.org/r/20221114085629.1910435-1-zengheng4@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/pxa/mmp-pcm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
+index 53fc49e32fbc..0791737c3bf3 100644
+--- a/sound/soc/pxa/mmp-pcm.c
++++ b/sound/soc/pxa/mmp-pcm.c
+@@ -98,7 +98,7 @@ static bool filter(struct dma_chan *chan, void *param)
+       devname = kasprintf(GFP_KERNEL, "%s.%d", dma_data->dma_res->name,
+               dma_data->ssp_id);
+-      if ((strcmp(dev_name(chan->device->dev), devname) == 0) &&
++      if (devname && (strcmp(dev_name(chan->device->dev), devname) == 0) &&
+               (chan->chan_id == dma_data->dma_res->start)) {
+               found = true;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/asoc-qcom-add-checks-for-devm_kcalloc.patch b/queue-5.10/asoc-qcom-add-checks-for-devm_kcalloc.patch
new file mode 100644 (file)
index 0000000..4e86b2f
--- /dev/null
@@ -0,0 +1,38 @@
+From 8a7e97f20ea03d50c7678e48d8827503787f44ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Nov 2022 14:05:10 +0000
+Subject: ASoC: qcom: Add checks for devm_kcalloc
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 1bf5ee979076ceb121ee51c95197d890b1cee7f4 ]
+
+As the devm_kcalloc may return NULL, the return value needs to be checked
+to avoid NULL poineter dereference.
+
+Fixes: 24caf8d9eb10 ("ASoC: qcom: lpass-sc7180: Add platform driver for lpass audio")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Link: https://lore.kernel.org/r/20221124140510.63468-1-yuancan@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/qcom/lpass-sc7180.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/qcom/lpass-sc7180.c b/sound/soc/qcom/lpass-sc7180.c
+index c647e627897a..cb4e9017cd77 100644
+--- a/sound/soc/qcom/lpass-sc7180.c
++++ b/sound/soc/qcom/lpass-sc7180.c
+@@ -129,6 +129,9 @@ static int sc7180_lpass_init(struct platform_device *pdev)
+       drvdata->clks = devm_kcalloc(dev, variant->num_clks,
+                                    sizeof(*drvdata->clks), GFP_KERNEL);
++      if (!drvdata->clks)
++              return -ENOMEM;
++
+       drvdata->num_clks = variant->num_clks;
+       for (i = 0; i < drvdata->num_clks; i++)
+-- 
+2.35.1
+
diff --git a/queue-5.10/binfmt_misc-fix-shift-out-of-bounds-in-check_special.patch b/queue-5.10/binfmt_misc-fix-shift-out-of-bounds-in-check_special.patch
new file mode 100644 (file)
index 0000000..880035a
--- /dev/null
@@ -0,0 +1,61 @@
+From 95f4f4939023b640b3ed7e94d08af89749ccf060 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 10:51:23 +0800
+Subject: binfmt_misc: fix shift-out-of-bounds in check_special_flags
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+[ Upstream commit 6a46bf558803dd2b959ca7435a5c143efe837217 ]
+
+UBSAN reported a shift-out-of-bounds warning:
+
+ left shift of 1 by 31 places cannot be represented in type 'int'
+ Call Trace:
+  <TASK>
+  __dump_stack lib/dump_stack.c:88 [inline]
+  dump_stack_lvl+0x8d/0xcf lib/dump_stack.c:106
+  ubsan_epilogue+0xa/0x44 lib/ubsan.c:151
+  __ubsan_handle_shift_out_of_bounds+0x1e7/0x208 lib/ubsan.c:322
+  check_special_flags fs/binfmt_misc.c:241 [inline]
+  create_entry fs/binfmt_misc.c:456 [inline]
+  bm_register_write+0x9d3/0xa20 fs/binfmt_misc.c:654
+  vfs_write+0x11e/0x580 fs/read_write.c:582
+  ksys_write+0xcf/0x120 fs/read_write.c:637
+  do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+  do_syscall_64+0x34/0x80 arch/x86/entry/common.c:80
+  entry_SYSCALL_64_after_hwframe+0x63/0xcd
+ RIP: 0033:0x4194e1
+
+Since the type of Node's flags is unsigned long, we should define these
+macros with same type too.
+
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20221102025123.1117184-1-liushixin2@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/binfmt_misc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
+index 11b5bf241955..ce0047feea72 100644
+--- a/fs/binfmt_misc.c
++++ b/fs/binfmt_misc.c
+@@ -44,10 +44,10 @@ static LIST_HEAD(entries);
+ static int enabled = 1;
+ enum {Enabled, Magic};
+-#define MISC_FMT_PRESERVE_ARGV0 (1 << 31)
+-#define MISC_FMT_OPEN_BINARY (1 << 30)
+-#define MISC_FMT_CREDENTIALS (1 << 29)
+-#define MISC_FMT_OPEN_FILE (1 << 28)
++#define MISC_FMT_PRESERVE_ARGV0 (1UL << 31)
++#define MISC_FMT_OPEN_BINARY (1UL << 30)
++#define MISC_FMT_CREDENTIALS (1UL << 29)
++#define MISC_FMT_OPEN_FILE (1UL << 28)
+ typedef struct {
+       struct list_head list;
+-- 
+2.35.1
+
diff --git a/queue-5.10/blk-mq-fix-possible-memleak-when-register-hctx-faile.patch b/queue-5.10/blk-mq-fix-possible-memleak-when-register-hctx-faile.patch
new file mode 100644 (file)
index 0000000..1419a3f
--- /dev/null
@@ -0,0 +1,86 @@
+From a7a2395d5547b85dae481b937fa38eb0cefa8fdd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 10:29:40 +0800
+Subject: blk-mq: fix possible memleak when register 'hctx' failed
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit 4b7a21c57b14fbcd0e1729150189e5933f5088e9 ]
+
+There's issue as follows when do fault injection test:
+unreferenced object 0xffff888132a9f400 (size 512):
+  comm "insmod", pid 308021, jiffies 4324277909 (age 509.733s)
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 08 f4 a9 32 81 88 ff ff  ...........2....
+    08 f4 a9 32 81 88 ff ff 00 00 00 00 00 00 00 00  ...2............
+  backtrace:
+    [<00000000e8952bb4>] kmalloc_node_trace+0x22/0xa0
+    [<00000000f9980e0f>] blk_mq_alloc_and_init_hctx+0x3f1/0x7e0
+    [<000000002e719efa>] blk_mq_realloc_hw_ctxs+0x1e6/0x230
+    [<000000004f1fda40>] blk_mq_init_allocated_queue+0x27e/0x910
+    [<00000000287123ec>] __blk_mq_alloc_disk+0x67/0xf0
+    [<00000000a2a34657>] 0xffffffffa2ad310f
+    [<00000000b173f718>] 0xffffffffa2af824a
+    [<0000000095a1dabb>] do_one_initcall+0x87/0x2a0
+    [<00000000f32fdf93>] do_init_module+0xdf/0x320
+    [<00000000cbe8541e>] load_module+0x3006/0x3390
+    [<0000000069ed1bdb>] __do_sys_finit_module+0x113/0x1b0
+    [<00000000a1a29ae8>] do_syscall_64+0x35/0x80
+    [<000000009cd878b0>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+Fault injection context as follows:
+ kobject_add
+ blk_mq_register_hctx
+ blk_mq_sysfs_register
+ blk_register_queue
+ device_add_disk
+ null_add_dev.part.0 [null_blk]
+
+As 'blk_mq_register_hctx' may already add some objects when failed halfway,
+but there isn't do fallback, caller don't know which objects add failed.
+To solve above issue just do fallback when add objects failed halfway in
+'blk_mq_register_hctx'.
+
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20221117022940.873959-1-yebin@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq-sysfs.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c
+index 7b52e7657b2d..f0bc3398f3ed 100644
+--- a/block/blk-mq-sysfs.c
++++ b/block/blk-mq-sysfs.c
+@@ -242,7 +242,7 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
+ {
+       struct request_queue *q = hctx->queue;
+       struct blk_mq_ctx *ctx;
+-      int i, ret;
++      int i, j, ret;
+       if (!hctx->nr_ctx)
+               return 0;
+@@ -254,9 +254,16 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
+       hctx_for_each_ctx(hctx, ctx, i) {
+               ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu);
+               if (ret)
+-                      break;
++                      goto out;
+       }
++      return 0;
++out:
++      hctx_for_each_ctx(hctx, ctx, j) {
++              if (j < i)
++                      kobject_del(&ctx->kobj);
++      }
++      kobject_del(&hctx->kobj);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/blktrace-fix-output-non-blktrace-event-when-blk_clas.patch b/queue-5.10/blktrace-fix-output-non-blktrace-event-when-blk_clas.patch
new file mode 100644 (file)
index 0000000..947ec12
--- /dev/null
@@ -0,0 +1,47 @@
+From eee463a6ae7f356bb526c4151fec43915aab6fea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 12:04:10 +0800
+Subject: blktrace: Fix output non-blktrace event when blk_classic option
+ enabled
+
+From: Yang Jihong <yangjihong1@huawei.com>
+
+[ Upstream commit f596da3efaf4130ff61cd029558845808df9bf99 ]
+
+When the blk_classic option is enabled, non-blktrace events must be
+filtered out. Otherwise, events of other types are output in the blktrace
+classic format, which is unexpected.
+
+The problem can be triggered in the following ways:
+
+  # echo 1 > /sys/kernel/debug/tracing/options/blk_classic
+  # echo 1 > /sys/kernel/debug/tracing/events/enable
+  # echo blk > /sys/kernel/debug/tracing/current_tracer
+  # cat /sys/kernel/debug/tracing/trace_pipe
+
+Fixes: c71a89615411 ("blktrace: add ftrace plugin")
+Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
+Link: https://lore.kernel.org/r/20221122040410.85113-1-yangjihong1@huawei.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/blktrace.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
+index 15a376f85e09..ab912cc60760 100644
+--- a/kernel/trace/blktrace.c
++++ b/kernel/trace/blktrace.c
+@@ -1592,7 +1592,8 @@ blk_trace_event_print_binary(struct trace_iterator *iter, int flags,
+ static enum print_line_t blk_tracer_print_line(struct trace_iterator *iter)
+ {
+-      if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
++      if ((iter->ent->type != TRACE_BLK) ||
++          !(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
+               return TRACE_TYPE_UNHANDLED;
+       return print_one_line(iter, true);
+-- 
+2.35.1
+
diff --git a/queue-5.10/bluetooth-btusb-don-t-call-kfree_skb-under-spin_lock.patch b/queue-5.10/bluetooth-btusb-don-t-call-kfree_skb-under-spin_lock.patch
new file mode 100644 (file)
index 0000000..bbce9ee
--- /dev/null
@@ -0,0 +1,45 @@
+From 34085a56a87d982c1f788b0c72d60ddbd6fce75f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 20:59:10 +0800
+Subject: Bluetooth: btusb: don't call kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit b15a6bd3c80c77faec8317319b97f976b1a08332 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave().
+
+Fixes: 803b58367ffb ("Bluetooth: btusb: Implement driver internal packet reassembly")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 54001ad5de9f..3d905fda9b29 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -661,13 +661,13 @@ static inline void btusb_free_frags(struct btusb_data *data)
+       spin_lock_irqsave(&data->rxlock, flags);
+-      kfree_skb(data->evt_skb);
++      dev_kfree_skb_irq(data->evt_skb);
+       data->evt_skb = NULL;
+-      kfree_skb(data->acl_skb);
++      dev_kfree_skb_irq(data->acl_skb);
+       data->acl_skb = NULL;
+-      kfree_skb(data->sco_skb);
++      dev_kfree_skb_irq(data->sco_skb);
+       data->sco_skb = NULL;
+       spin_unlock_irqrestore(&data->rxlock, flags);
+-- 
+2.35.1
+
diff --git a/queue-5.10/bluetooth-hci_bcsp-don-t-call-kfree_skb-under-spin_l.patch b/queue-5.10/bluetooth-hci_bcsp-don-t-call-kfree_skb-under-spin_l.patch
new file mode 100644 (file)
index 0000000..2edf993
--- /dev/null
@@ -0,0 +1,37 @@
+From 9ea41c58998e53065ea22eac652814dfa0de0af1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 10:18:33 +0800
+Subject: Bluetooth: hci_bcsp: don't call kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 7b503e339c1a80bf0051ec2d19c3bc777014ac61 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave().
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_bcsp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
+index cf4a56095817..8055f63603f4 100644
+--- a/drivers/bluetooth/hci_bcsp.c
++++ b/drivers/bluetooth/hci_bcsp.c
+@@ -378,7 +378,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
+               i++;
+               __skb_unlink(skb, &bcsp->unack);
+-              kfree_skb(skb);
++              dev_kfree_skb_irq(skb);
+       }
+       if (skb_queue_empty(&bcsp->unack))
+-- 
+2.35.1
+
diff --git a/queue-5.10/bluetooth-hci_core-don-t-call-kfree_skb-under-spin_l.patch b/queue-5.10/bluetooth-hci_core-don-t-call-kfree_skb-under-spin_l.patch
new file mode 100644 (file)
index 0000000..6be6746
--- /dev/null
@@ -0,0 +1,37 @@
+From b90c0fdd805909507a526fd01f2c0a622d92180a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 10:18:34 +0800
+Subject: Bluetooth: hci_core: don't call kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 39c1eb6fcbae8ce9bb71b2ac5cb609355a2b181b ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave().
+
+Fixes: 9238f36a5a50 ("Bluetooth: Add request cmd_complete and cmd_status functions")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index f8aab38ab595..2af1477a05ca 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -4910,7 +4910,7 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
+                       *req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
+               else
+                       *req_complete = bt_cb(skb)->hci.req_complete;
+-              kfree_skb(skb);
++              dev_kfree_skb_irq(skb);
+       }
+       spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/bluetooth-hci_h5-don-t-call-kfree_skb-under-spin_loc.patch b/queue-5.10/bluetooth-hci_h5-don-t-call-kfree_skb-under-spin_loc.patch
new file mode 100644 (file)
index 0000000..4ddb464
--- /dev/null
@@ -0,0 +1,37 @@
+From bddc3b7b4220360bf5f883e0d335b814cdb90d69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 10:18:32 +0800
+Subject: Bluetooth: hci_h5: don't call kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 383630cc6758d619874c2e8bb2f68a61f3f9ef6e ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave().
+
+Fixes: 43eb12d78960 ("Bluetooth: Fix/implement Three-wire reliable packet sending")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_h5.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
+index 996729e78105..7f70a677b92b 100644
+--- a/drivers/bluetooth/hci_h5.c
++++ b/drivers/bluetooth/hci_h5.c
+@@ -299,7 +299,7 @@ static void h5_pkt_cull(struct h5 *h5)
+                       break;
+               __skb_unlink(skb, &h5->unack);
+-              kfree_skb(skb);
++              dev_kfree_skb_irq(skb);
+       }
+       if (skb_queue_empty(&h5->unack))
+-- 
+2.35.1
+
diff --git a/queue-5.10/bluetooth-hci_ll-don-t-call-kfree_skb-under-spin_loc.patch b/queue-5.10/bluetooth-hci_ll-don-t-call-kfree_skb-under-spin_loc.patch
new file mode 100644 (file)
index 0000000..d9ecb9d
--- /dev/null
@@ -0,0 +1,37 @@
+From 4cb4d32390aba6848279dabef63f71a3b1597735 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 10:18:31 +0800
+Subject: Bluetooth: hci_ll: don't call kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 8f458f783dfbb19c1f1cb58ed06eeb701f52091b ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave().
+
+Fixes: 166d2f6a4332 ("[Bluetooth] Add UART driver for Texas Instruments' BRF63xx chips")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_ll.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
+index 8bfe024d1fcd..7495ca34c9e7 100644
+--- a/drivers/bluetooth/hci_ll.c
++++ b/drivers/bluetooth/hci_ll.c
+@@ -345,7 +345,7 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
+       default:
+               BT_ERR("illegal hcill state: %ld (losing packet)",
+                      ll->hcill_state);
+-              kfree_skb(skb);
++              dev_kfree_skb_irq(skb);
+               break;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/bluetooth-hci_qca-don-t-call-kfree_skb-under-spin_lo.patch b/queue-5.10/bluetooth-hci_qca-don-t-call-kfree_skb-under-spin_lo.patch
new file mode 100644 (file)
index 0000000..d95e454
--- /dev/null
@@ -0,0 +1,37 @@
+From 6fca26544397c0773b0e7eeae3c3b85faf05e714 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 10:18:30 +0800
+Subject: Bluetooth: hci_qca: don't call kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit df4cfc91208e0a98f078223793f5871b1a82cc54 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave().
+
+Fixes: 0ff252c1976d ("Bluetooth: hciuart: Add support QCA chipset for UART")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_qca.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index eea18aed17f8..60b0e13bb9fc 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -905,7 +905,7 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
+       default:
+               BT_ERR("Illegal tx state: %d (losing packet)",
+                      qca->tx_ibs_state);
+-              kfree_skb(skb);
++              dev_kfree_skb_irq(skb);
+               break;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/bluetooth-rfcomm-don-t-call-kfree_skb-under-spin_loc.patch b/queue-5.10/bluetooth-rfcomm-don-t-call-kfree_skb-under-spin_loc.patch
new file mode 100644 (file)
index 0000000..39c1392
--- /dev/null
@@ -0,0 +1,37 @@
+From e0aeb593d7f46a735246803945775e1ad1c63813 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 10:18:35 +0800
+Subject: Bluetooth: RFCOMM: don't call kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 0ba18967d4544955b2eff2fbc4f2a8750c4df90a ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave().
+
+Fixes: 81be03e026dc ("Bluetooth: RFCOMM: Replace use of memcpy_from_msg with bt_skb_sendmmsg")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/rfcomm/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
+index 7324764384b6..8d6fce9005bd 100644
+--- a/net/bluetooth/rfcomm/core.c
++++ b/net/bluetooth/rfcomm/core.c
+@@ -590,7 +590,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
+               ret = rfcomm_dlc_send_frag(d, frag);
+               if (ret < 0) {
+-                      kfree_skb(frag);
++                      dev_kfree_skb_irq(frag);
+                       goto unlock;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.10/bonding-fix-link-recovery-in-mode-2-when-updelay-is-.patch b/queue-5.10/bonding-fix-link-recovery-in-mode-2-when-updelay-is-.patch
new file mode 100644 (file)
index 0000000..cc043fb
--- /dev/null
@@ -0,0 +1,49 @@
+From d4f1a1cdf1a1193a3afb447797479ede1bf41275 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 16:24:29 -0500
+Subject: bonding: fix link recovery in mode 2 when updelay is nonzero
+
+From: Jonathan Toppins <jtoppins@redhat.com>
+
+[ Upstream commit f8a65ab2f3ff7410921ebbf0dc55453102c33c56 ]
+
+Before this change when a bond in mode 2 lost link, all of its slaves
+lost link, the bonding device would never recover even after the
+expiration of updelay. This change removes the updelay when the bond
+currently has no usable links. Conforming to bonding.txt section 13.1
+paragraph 4.
+
+Fixes: 41f891004063 ("bonding: ignore updelay param when there is no active slave")
+Signed-off-by: Jonathan Toppins <jtoppins@redhat.com>
+Acked-by: Jay Vosburgh <jay.vosburgh@canonical.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index f38a6ce5749b..e66092518fdd 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -2398,7 +2398,16 @@ static int bond_miimon_inspect(struct bonding *bond)
+       struct slave *slave;
+       bool ignore_updelay;
+-      ignore_updelay = !rcu_dereference(bond->curr_active_slave);
++      if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) {
++              ignore_updelay = !rcu_dereference(bond->curr_active_slave);
++      } else {
++              struct bond_up_slave *usable_slaves;
++
++              usable_slaves = rcu_dereference(bond->usable_slaves);
++
++              if (usable_slaves && usable_slaves->count == 0)
++                      ignore_updelay = true;
++      }
+       bond_for_each_slave_rcu(bond, slave, iter) {
+               bond_propose_link_state(slave, BOND_LINK_NOCHANGE);
+-- 
+2.35.1
+
diff --git a/queue-5.10/bonding-uninitialized-variable-in-bond_miimon_inspec.patch b/queue-5.10/bonding-uninitialized-variable-in-bond_miimon_inspec.patch
new file mode 100644 (file)
index 0000000..320494d
--- /dev/null
@@ -0,0 +1,41 @@
+From e2bcf84b49a29837f056e6c1f2dd979656c7e4cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 14:06:14 +0300
+Subject: bonding: uninitialized variable in bond_miimon_inspect()
+
+From: Dan Carpenter <error27@gmail.com>
+
+[ Upstream commit e5214f363dabca240446272dac54d404501ad5e5 ]
+
+The "ignore_updelay" variable needs to be initialized to false.
+
+Fixes: f8a65ab2f3ff ("bonding: fix link recovery in mode 2 when updelay is nonzero")
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Acked-by: Jay Vosburgh <jay.vosburgh@canonical.com>
+Link: https://lore.kernel.org/r/Y4SWJlh3ohJ6EPTL@kili
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index e66092518fdd..c40b92f8d16b 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -2393,10 +2393,10 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
+ /* called with rcu_read_lock() */
+ static int bond_miimon_inspect(struct bonding *bond)
+ {
++      bool ignore_updelay = false;
+       int link_state, commit = 0;
+       struct list_head *iter;
+       struct slave *slave;
+-      bool ignore_updelay;
+       if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) {
+               ignore_updelay = !rcu_dereference(bond->curr_active_slave);
+-- 
+2.35.1
+
diff --git a/queue-5.10/bpf-check-the-other-end-of-slot_type-for-stack_spill.patch b/queue-5.10/bpf-check-the-other-end-of-slot_type-for-stack_spill.patch
new file mode 100644 (file)
index 0000000..3ccdc8c
--- /dev/null
@@ -0,0 +1,147 @@
+From 23d7a74253fb17ee3b883b583320d53da786679b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Sep 2021 17:49:34 -0700
+Subject: bpf: Check the other end of slot_type for STACK_SPILL
+
+From: Martin KaFai Lau <kafai@fb.com>
+
+[ Upstream commit 27113c59b6d0a587b29ae72d4ff3f832f58b0651 ]
+
+Every 8 bytes of the stack is tracked by a bpf_stack_state.
+Within each bpf_stack_state, there is a 'u8 slot_type[8]' to track
+the type of each byte.  Verifier tests slot_type[0] == STACK_SPILL
+to decide if the spilled reg state is saved.  Verifier currently only
+saves the reg state if the whole 8 bytes are spilled to the stack,
+so checking the slot_type[7] is the same as checking slot_type[0].
+
+The later patch will allow verifier to save the bounded scalar
+reg also for <8 bytes spill.  There is a llvm patch [1] to ensure
+the <8 bytes spill will be 8-byte aligned,  so checking
+slot_type[7] instead of slot_type[0] is required.
+
+While at it, this patch refactors the slot_type[0] == STACK_SPILL
+test into a new function is_spilled_reg() and change the
+slot_type[0] check to slot_type[7] check in there also.
+
+[1] https://reviews.llvm.org/D109073
+
+Signed-off-by: Martin KaFai Lau <kafai@fb.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20210922004934.624194-1-kafai@fb.com
+Stable-dep-of: 529409ea92d5 ("bpf: propagate precision across all frames, not just the last one")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 30 +++++++++++++++++++-----------
+ 1 file changed, 19 insertions(+), 11 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 30e0fa1bd83c..034eb3030ce9 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -562,6 +562,14 @@ const char *kernel_type_name(u32 id)
+                                 btf_type_by_id(btf_vmlinux, id)->name_off);
+ }
++/* The reg state of a pointer or a bounded scalar was saved when
++ * it was spilled to the stack.
++ */
++static bool is_spilled_reg(const struct bpf_stack_state *stack)
++{
++      return stack->slot_type[BPF_REG_SIZE - 1] == STACK_SPILL;
++}
++
+ static void print_verifier_state(struct bpf_verifier_env *env,
+                                const struct bpf_func_state *state)
+ {
+@@ -666,7 +674,7 @@ static void print_verifier_state(struct bpf_verifier_env *env,
+                       continue;
+               verbose(env, " fp%d", (-i - 1) * BPF_REG_SIZE);
+               print_liveness(env, state->stack[i].spilled_ptr.live);
+-              if (state->stack[i].slot_type[0] == STACK_SPILL) {
++              if (is_spilled_reg(&state->stack[i])) {
+                       reg = &state->stack[i].spilled_ptr;
+                       t = reg->type;
+                       verbose(env, "=%s", reg_type_str[t]);
+@@ -2009,7 +2017,7 @@ static void mark_all_scalars_precise(struct bpf_verifier_env *env,
+                               reg->precise = true;
+                       }
+                       for (j = 0; j < func->allocated_stack / BPF_REG_SIZE; j++) {
+-                              if (func->stack[j].slot_type[0] != STACK_SPILL)
++                              if (!is_spilled_reg(&func->stack[j]))
+                                       continue;
+                               reg = &func->stack[j].spilled_ptr;
+                               if (reg->type != SCALAR_VALUE)
+@@ -2051,7 +2059,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+       }
+       while (spi >= 0) {
+-              if (func->stack[spi].slot_type[0] != STACK_SPILL) {
++              if (!is_spilled_reg(&func->stack[spi])) {
+                       stack_mask = 0;
+                       break;
+               }
+@@ -2150,7 +2158,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+                               return 0;
+                       }
+-                      if (func->stack[i].slot_type[0] != STACK_SPILL) {
++                      if (!is_spilled_reg(&func->stack[i])) {
+                               stack_mask &= ~(1ull << i);
+                               continue;
+                       }
+@@ -2348,7 +2356,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
+               /* regular write of data into stack destroys any spilled ptr */
+               state->stack[spi].spilled_ptr.type = NOT_INIT;
+               /* Mark slots as STACK_MISC if they belonged to spilled ptr. */
+-              if (state->stack[spi].slot_type[0] == STACK_SPILL)
++              if (is_spilled_reg(&state->stack[spi]))
+                       for (i = 0; i < BPF_REG_SIZE; i++)
+                               state->stack[spi].slot_type[i] = STACK_MISC;
+@@ -2562,7 +2570,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
+       stype = reg_state->stack[spi].slot_type;
+       reg = &reg_state->stack[spi].spilled_ptr;
+-      if (stype[0] == STACK_SPILL) {
++      if (is_spilled_reg(&reg_state->stack[spi])) {
+               if (size != BPF_REG_SIZE) {
+                       if (reg->type != SCALAR_VALUE) {
+                               verbose_linfo(env, env->insn_idx, "; ");
+@@ -4081,11 +4089,11 @@ static int check_stack_range_initialized(
+                       goto mark;
+               }
+-              if (state->stack[spi].slot_type[0] == STACK_SPILL &&
++              if (is_spilled_reg(&state->stack[spi]) &&
+                   state->stack[spi].spilled_ptr.type == PTR_TO_BTF_ID)
+                       goto mark;
+-              if (state->stack[spi].slot_type[0] == STACK_SPILL &&
++              if (is_spilled_reg(&state->stack[spi]) &&
+                   (state->stack[spi].spilled_ptr.type == SCALAR_VALUE ||
+                    env->allow_ptr_leaks)) {
+                       if (clobber) {
+@@ -9282,9 +9290,9 @@ static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old,
+                        * return false to continue verification of this path
+                        */
+                       return false;
+-              if (i % BPF_REG_SIZE)
++              if (i % BPF_REG_SIZE != BPF_REG_SIZE - 1)
+                       continue;
+-              if (old->stack[spi].slot_type[0] != STACK_SPILL)
++              if (!is_spilled_reg(&old->stack[spi]))
+                       continue;
+               if (!regsafe(env, &old->stack[spi].spilled_ptr,
+                            &cur->stack[spi].spilled_ptr, idmap))
+@@ -9491,7 +9499,7 @@ static int propagate_precision(struct bpf_verifier_env *env,
+       }
+       for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) {
+-              if (state->stack[i].slot_type[0] != STACK_SPILL)
++              if (!is_spilled_reg(&state->stack[i]))
+                       continue;
+               state_reg = &state->stack[i].spilled_ptr;
+               if (state_reg->type != SCALAR_VALUE ||
+-- 
+2.35.1
+
diff --git a/queue-5.10/bpf-fix-slot-type-check-in-check_stack_write_var_off.patch b/queue-5.10/bpf-fix-slot-type-check-in-check_stack_write_var_off.patch
new file mode 100644 (file)
index 0000000..ab26a48
--- /dev/null
@@ -0,0 +1,57 @@
+From 9345213f25d23a3f248a4566566216cb422e728b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 00:39:53 +0530
+Subject: bpf: Fix slot type check in check_stack_write_var_off
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit f5e477a861e4a20d8a1c5f7a245f3a3c3c376b03 ]
+
+For the case where allow_ptr_leaks is false, code is checking whether
+slot type is STACK_INVALID and STACK_SPILL and rejecting other cases.
+This is a consequence of incorrectly checking for register type instead
+of the slot type (NOT_INIT and SCALAR_VALUE respectively). Fix the
+check.
+
+Fixes: 01f810ace9ed ("bpf: Allow variable-offset stack access")
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Link: https://lore.kernel.org/r/20221103191013.1236066-5-memxor@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 50364031eb4d..4d62822f5502 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -2439,14 +2439,17 @@ static int check_stack_write_var_off(struct bpf_verifier_env *env,
+               spi = slot / BPF_REG_SIZE;
+               stype = &state->stack[spi].slot_type[slot % BPF_REG_SIZE];
+-              if (!env->allow_ptr_leaks
+-                              && *stype != NOT_INIT
+-                              && *stype != SCALAR_VALUE) {
+-                      /* Reject the write if there's are spilled pointers in
+-                       * range. If we didn't reject here, the ptr status
+-                       * would be erased below (even though not all slots are
+-                       * actually overwritten), possibly opening the door to
+-                       * leaks.
++              if (!env->allow_ptr_leaks && *stype != STACK_MISC && *stype != STACK_ZERO) {
++                      /* Reject the write if range we may write to has not
++                       * been initialized beforehand. If we didn't reject
++                       * here, the ptr status would be erased below (even
++                       * though not all slots are actually overwritten),
++                       * possibly opening the door to leaks.
++                       *
++                       * We do however catch STACK_INVALID case below, and
++                       * only allow reading possibly uninitialized memory
++                       * later for CAP_PERFMON, as the write may not happen to
++                       * that slot.
+                        */
+                       verbose(env, "spilled ptr in range of var-offset stack write; insn %d, ptr off: %d",
+                               insn_idx, i);
+-- 
+2.35.1
+
diff --git a/queue-5.10/bpf-make-sure-skb-len-0-when-redirecting-to-a-tunnel.patch b/queue-5.10/bpf-make-sure-skb-len-0-when-redirecting-to-a-tunnel.patch
new file mode 100644 (file)
index 0000000..c822248
--- /dev/null
@@ -0,0 +1,73 @@
+From fc6749651374d1e64dda8bcc4491fb4801c773c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 15:55:37 -0700
+Subject: bpf: make sure skb->len != 0 when redirecting to a tunneling device
+
+From: Stanislav Fomichev <sdf@google.com>
+
+[ Upstream commit 07ec7b502800ba9f7b8b15cb01dd6556bb41aaca ]
+
+syzkaller managed to trigger another case where skb->len == 0
+when we enter __dev_queue_xmit:
+
+WARNING: CPU: 0 PID: 2470 at include/linux/skbuff.h:2576 skb_assert_len include/linux/skbuff.h:2576 [inline]
+WARNING: CPU: 0 PID: 2470 at include/linux/skbuff.h:2576 __dev_queue_xmit+0x2069/0x35e0 net/core/dev.c:4295
+
+Call Trace:
+ dev_queue_xmit+0x17/0x20 net/core/dev.c:4406
+ __bpf_tx_skb net/core/filter.c:2115 [inline]
+ __bpf_redirect_no_mac net/core/filter.c:2140 [inline]
+ __bpf_redirect+0x5fb/0xda0 net/core/filter.c:2163
+ ____bpf_clone_redirect net/core/filter.c:2447 [inline]
+ bpf_clone_redirect+0x247/0x390 net/core/filter.c:2419
+ bpf_prog_48159a89cb4a9a16+0x59/0x5e
+ bpf_dispatcher_nop_func include/linux/bpf.h:897 [inline]
+ __bpf_prog_run include/linux/filter.h:596 [inline]
+ bpf_prog_run include/linux/filter.h:603 [inline]
+ bpf_test_run+0x46c/0x890 net/bpf/test_run.c:402
+ bpf_prog_test_run_skb+0xbdc/0x14c0 net/bpf/test_run.c:1170
+ bpf_prog_test_run+0x345/0x3c0 kernel/bpf/syscall.c:3648
+ __sys_bpf+0x43a/0x6c0 kernel/bpf/syscall.c:5005
+ __do_sys_bpf kernel/bpf/syscall.c:5091 [inline]
+ __se_sys_bpf kernel/bpf/syscall.c:5089 [inline]
+ __x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:5089
+ do_syscall_64+0x54/0x70 arch/x86/entry/common.c:48
+ entry_SYSCALL_64_after_hwframe+0x61/0xc6
+
+The reproducer doesn't really reproduce outside of syzkaller
+environment, so I'm taking a guess here. It looks like we
+do generate correct ETH_HLEN-sized packet, but we redirect
+the packet to the tunneling device. Before we do so, we
+__skb_pull l2 header and arrive again at skb->len == 0.
+Doesn't seem like we can do anything better than having
+an explicit check after __skb_pull?
+
+Cc: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot+f635e86ec3fa0a37e019@syzkaller.appspotmail.com
+Signed-off-by: Stanislav Fomichev <sdf@google.com>
+Link: https://lore.kernel.org/r/20221027225537.353077-1-sdf@google.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index ef7e74260afc..e3cdbd4996e0 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2132,6 +2132,10 @@ static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev,
+       if (mlen) {
+               __skb_pull(skb, mlen);
++              if (unlikely(!skb->len)) {
++                      kfree_skb(skb);
++                      return -ERANGE;
++              }
+               /* At ingress, the mac header has already been pulled once.
+                * At egress, skb_pospull_rcsum has to be done in case that
+-- 
+2.35.1
+
diff --git a/queue-5.10/bpf-move-skb-len-0-checks-into-__bpf_redirect.patch b/queue-5.10/bpf-move-skb-len-0-checks-into-__bpf_redirect.patch
new file mode 100644 (file)
index 0000000..378cd20
--- /dev/null
@@ -0,0 +1,66 @@
+From 89718cf1356bb2cf3572dfa1f74434fb15982edc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 10:03:39 -0800
+Subject: bpf: Move skb->len == 0 checks into __bpf_redirect
+
+From: Stanislav Fomichev <sdf@google.com>
+
+[ Upstream commit 114039b342014680911c35bd6b72624180fd669a ]
+
+To avoid potentially breaking existing users.
+
+Both mac/no-mac cases have to be amended; mac_header >= network_header
+is not enough (verified with a new test, see next patch).
+
+Fixes: fd1894224407 ("bpf: Don't redirect packets with invalid pkt_len")
+Signed-off-by: Stanislav Fomichev <sdf@google.com>
+Link: https://lore.kernel.org/r/20221121180340.1983627-1-sdf@google.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bpf/test_run.c | 3 ---
+ net/core/filter.c  | 7 ++++++-
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
+index 717b01ff9b2b..7df14a0e380c 100644
+--- a/net/bpf/test_run.c
++++ b/net/bpf/test_run.c
+@@ -442,9 +442,6 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb)
+ {
+       struct qdisc_skb_cb *cb = (struct qdisc_skb_cb *)skb->cb;
+-      if (!skb->len)
+-              return -EINVAL;
+-
+       if (!__skb)
+               return 0;
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 4c22e6d1da74..ef7e74260afc 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2125,6 +2125,11 @@ static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev,
+ {
+       unsigned int mlen = skb_network_offset(skb);
++      if (unlikely(skb->len <= mlen)) {
++              kfree_skb(skb);
++              return -ERANGE;
++      }
++
+       if (mlen) {
+               __skb_pull(skb, mlen);
+@@ -2146,7 +2151,7 @@ static int __bpf_redirect_common(struct sk_buff *skb, struct net_device *dev,
+                                u32 flags)
+ {
+       /* Verify that a link layer header is carried */
+-      if (unlikely(skb->mac_header >= skb->network_header)) {
++      if (unlikely(skb->mac_header >= skb->network_header || skb->len == 0)) {
+               kfree_skb(skb);
+               return -ERANGE;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/bpf-prevent-decl_tag-from-being-referenced-in-func_p.patch b/queue-5.10/bpf-prevent-decl_tag-from-being-referenced-in-func_p.patch
new file mode 100644 (file)
index 0000000..b8679f4
--- /dev/null
@@ -0,0 +1,55 @@
+From 2d4394b9841569a0115304b54faf79e0891ee0d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 19:54:22 -0800
+Subject: bpf: Prevent decl_tag from being referenced in func_proto arg
+
+From: Stanislav Fomichev <sdf@google.com>
+
+[ Upstream commit f17472d4599697d701aa239b4c475a506bccfd19 ]
+
+Syzkaller managed to hit another decl_tag issue:
+
+  btf_func_proto_check kernel/bpf/btf.c:4506 [inline]
+  btf_check_all_types kernel/bpf/btf.c:4734 [inline]
+  btf_parse_type_sec+0x1175/0x1980 kernel/bpf/btf.c:4763
+  btf_parse kernel/bpf/btf.c:5042 [inline]
+  btf_new_fd+0x65a/0xb00 kernel/bpf/btf.c:6709
+  bpf_btf_load+0x6f/0x90 kernel/bpf/syscall.c:4342
+  __sys_bpf+0x50a/0x6c0 kernel/bpf/syscall.c:5034
+  __do_sys_bpf kernel/bpf/syscall.c:5093 [inline]
+  __se_sys_bpf kernel/bpf/syscall.c:5091 [inline]
+  __x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:5091
+  do_syscall_64+0x54/0x70 arch/x86/entry/common.c:48
+
+This seems similar to commit ea68376c8bed ("bpf: prevent decl_tag from being
+referenced in func_proto") but for the argument.
+
+Reported-by: syzbot+8dd0551dda6020944c5d@syzkaller.appspotmail.com
+Signed-off-by: Stanislav Fomichev <sdf@google.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Yonghong Song <yhs@fb.com>
+Link: https://lore.kernel.org/bpf/20221123035422.872531-2-sdf@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/btf.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 9232938e3f96..52e704860739 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -3675,6 +3675,11 @@ static int btf_func_proto_check(struct btf_verifier_env *env,
+                       break;
+               }
++              if (btf_type_is_resolve_source_only(arg_type)) {
++                      btf_verifier_log_type(env, t, "Invalid arg#%u", i + 1);
++                      return -EINVAL;
++              }
++
+               if (args[i].name_off &&
+                   (!btf_name_offset_valid(btf, args[i].name_off) ||
+                    !btf_name_valid_identifier(btf, args[i].name_off))) {
+-- 
+2.35.1
+
diff --git a/queue-5.10/bpf-propagate-precision-across-all-frames-not-just-t.patch b/queue-5.10/bpf-propagate-precision-across-all-frames-not-just-t.patch
new file mode 100644 (file)
index 0000000..9516009
--- /dev/null
@@ -0,0 +1,160 @@
+From 293e65277d9a3114a460b46a23ef48273132efa2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 09:36:45 -0700
+Subject: bpf: propagate precision across all frames, not just the last one
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit 529409ea92d590659be487ba0839710329bd8074 ]
+
+When equivalent completed state is found and it has additional precision
+restrictions, BPF verifier propagates precision to
+currently-being-verified state chain (i.e., including parent states) so
+that if some of the states in the chain are not yet completed, necessary
+precision restrictions are enforced.
+
+Unfortunately, right now this happens only for the last frame (deepest
+active subprogram's frame), not all the frames. This can lead to
+incorrect matching of states due to missing precision marker. Currently
+this doesn't seem possible as BPF verifier forces everything to precise
+when validated BPF program has any subprograms. But with the next patch
+lifting this restriction, this becomes problematic.
+
+In fact, without this fix, we'll start getting failure in one of the
+existing test_verifier test cases:
+
+  #906/p precise: cross frame pruning FAIL
+  Unexpected success to load!
+  verification time 48 usec
+  stack depth 0+0
+  processed 26 insns (limit 1000000) max_states_per_insn 3 total_states 17 peak_states 17 mark_read 8
+
+This patch adds precision propagation across all frames.
+
+Fixes: a3ce685dd01a ("bpf: fix precision tracking")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/r/20221104163649.121784-3-andrii@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 71 ++++++++++++++++++++++++-------------------
+ 1 file changed, 39 insertions(+), 32 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 034eb3030ce9..232c93357b90 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -2027,7 +2027,7 @@ static void mark_all_scalars_precise(struct bpf_verifier_env *env,
+               }
+ }
+-static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
++static int __mark_chain_precision(struct bpf_verifier_env *env, int frame, int regno,
+                                 int spi)
+ {
+       struct bpf_verifier_state *st = env->cur_state;
+@@ -2044,7 +2044,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+       if (!env->bpf_capable)
+               return 0;
+-      func = st->frame[st->curframe];
++      func = st->frame[frame];
+       if (regno >= 0) {
+               reg = &func->regs[regno];
+               if (reg->type != SCALAR_VALUE) {
+@@ -2125,7 +2125,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+                       break;
+               new_marks = false;
+-              func = st->frame[st->curframe];
++              func = st->frame[frame];
+               bitmap_from_u64(mask, reg_mask);
+               for_each_set_bit(i, mask, 32) {
+                       reg = &func->regs[i];
+@@ -2191,12 +2191,17 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+ static int mark_chain_precision(struct bpf_verifier_env *env, int regno)
+ {
+-      return __mark_chain_precision(env, regno, -1);
++      return __mark_chain_precision(env, env->cur_state->curframe, regno, -1);
+ }
+-static int mark_chain_precision_stack(struct bpf_verifier_env *env, int spi)
++static int mark_chain_precision_frame(struct bpf_verifier_env *env, int frame, int regno)
+ {
+-      return __mark_chain_precision(env, -1, spi);
++      return __mark_chain_precision(env, frame, regno, -1);
++}
++
++static int mark_chain_precision_stack_frame(struct bpf_verifier_env *env, int frame, int spi)
++{
++      return __mark_chain_precision(env, frame, -1, spi);
+ }
+ static bool is_spillable_regtype(enum bpf_reg_type type)
+@@ -9483,34 +9488,36 @@ static int propagate_precision(struct bpf_verifier_env *env,
+ {
+       struct bpf_reg_state *state_reg;
+       struct bpf_func_state *state;
+-      int i, err = 0;
++      int i, err = 0, fr;
+-      state = old->frame[old->curframe];
+-      state_reg = state->regs;
+-      for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
+-              if (state_reg->type != SCALAR_VALUE ||
+-                  !state_reg->precise)
+-                      continue;
+-              if (env->log.level & BPF_LOG_LEVEL2)
+-                      verbose(env, "propagating r%d\n", i);
+-              err = mark_chain_precision(env, i);
+-              if (err < 0)
+-                      return err;
+-      }
++      for (fr = old->curframe; fr >= 0; fr--) {
++              state = old->frame[fr];
++              state_reg = state->regs;
++              for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
++                      if (state_reg->type != SCALAR_VALUE ||
++                          !state_reg->precise)
++                              continue;
++                      if (env->log.level & BPF_LOG_LEVEL2)
++                              verbose(env, "frame %d: propagating r%d\n", i, fr);
++                      err = mark_chain_precision_frame(env, fr, i);
++                      if (err < 0)
++                              return err;
++              }
+-      for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) {
+-              if (!is_spilled_reg(&state->stack[i]))
+-                      continue;
+-              state_reg = &state->stack[i].spilled_ptr;
+-              if (state_reg->type != SCALAR_VALUE ||
+-                  !state_reg->precise)
+-                      continue;
+-              if (env->log.level & BPF_LOG_LEVEL2)
+-                      verbose(env, "propagating fp%d\n",
+-                              (-i - 1) * BPF_REG_SIZE);
+-              err = mark_chain_precision_stack(env, i);
+-              if (err < 0)
+-                      return err;
++              for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) {
++                      if (!is_spilled_reg(&state->stack[i]))
++                              continue;
++                      state_reg = &state->stack[i].spilled_ptr;
++                      if (state_reg->type != SCALAR_VALUE ||
++                          !state_reg->precise)
++                              continue;
++                      if (env->log.level & BPF_LOG_LEVEL2)
++                              verbose(env, "frame %d: propagating fp%d\n",
++                                      (-i - 1) * BPF_REG_SIZE, fr);
++                      err = mark_chain_precision_stack_frame(env, fr, i);
++                      if (err < 0)
++                              return err;
++              }
+       }
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/bpf-propagate-precision-in-alu-alu64-operations.patch b/queue-5.10/bpf-propagate-precision-in-alu-alu64-operations.patch
new file mode 100644 (file)
index 0000000..b0d3567
--- /dev/null
@@ -0,0 +1,89 @@
+From c16ca67b6a1345c714ffa830fd283a2f9e9d4417 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 09:36:44 -0700
+Subject: bpf: propagate precision in ALU/ALU64 operations
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit a3b666bfa9c9edc05bca62a87abafe0936bd7f97 ]
+
+When processing ALU/ALU64 operations (apart from BPF_MOV, which is
+handled correctly already; and BPF_NEG and BPF_END are special and don't
+have source register), if destination register is already marked
+precise, this causes problem with potentially missing precision tracking
+for the source register. E.g., when we have r1 >>= r5 and r1 is marked
+precise, but r5 isn't, this will lead to r5 staying as imprecise. This
+is due to the precision backtracking logic stopping early when it sees
+r1 is already marked precise. If r1 wasn't precise, we'd keep
+backtracking and would add r5 to the set of registers that need to be
+marked precise. So there is a discrepancy here which can lead to invalid
+and incompatible states matched due to lack of precision marking on r5.
+If r1 wasn't precise, precision backtracking would correctly mark both
+r1 and r5 as precise.
+
+This is simple to fix, though. During the forward instruction simulation
+pass, for arithmetic operations of `scalar <op>= scalar` form (where
+<op> is ALU or ALU64 operations), if destination register is already
+precise, mark source register as precise. This applies only when both
+involved registers are SCALARs. `ptr += scalar` and `scalar += ptr`
+cases are already handled correctly.
+
+This does have (negative) effect on some selftest programs and few
+Cilium programs.  ~/baseline-tmp-results.csv are veristat results with
+this patch, while ~/baseline-results.csv is without it. See post
+scriptum for instructions on how to make Cilium programs testable with
+veristat. Correctness has a price.
+
+$ ./veristat -C -e file,prog,insns,states ~/baseline-results.csv ~/baseline-tmp-results.csv | grep -v '+0'
+File                     Program               Total insns (A)  Total insns (B)  Total insns (DIFF)  Total states (A)  Total states (B)  Total states (DIFF)
+-----------------------  --------------------  ---------------  ---------------  ------------------  ----------------  ----------------  -------------------
+bpf_cubic.bpf.linked1.o  bpf_cubic_cong_avoid              997             1700      +703 (+70.51%)                62                90        +28 (+45.16%)
+test_l4lb.bpf.linked1.o  balancer_ingress                 4559             5469      +910 (+19.96%)               118               126          +8 (+6.78%)
+-----------------------  --------------------  ---------------  ---------------  ------------------  ----------------  ----------------  -------------------
+
+$ ./veristat -C -e file,prog,verdict,insns,states ~/baseline-results-cilium.csv ~/baseline-tmp-results-cilium.csv | grep -v '+0'
+File           Program                         Total insns (A)  Total insns (B)  Total insns (DIFF)  Total states (A)  Total states (B)  Total states (DIFF)
+-------------  ------------------------------  ---------------  ---------------  ------------------  ----------------  ----------------  -------------------
+bpf_host.o     tail_nodeport_nat_ingress_ipv6             4448             5261      +813 (+18.28%)               234               247         +13 (+5.56%)
+bpf_host.o     tail_nodeport_nat_ipv6_egress              3396             3446        +50 (+1.47%)               201               203          +2 (+1.00%)
+bpf_lxc.o      tail_nodeport_nat_ingress_ipv6             4448             5261      +813 (+18.28%)               234               247         +13 (+5.56%)
+bpf_overlay.o  tail_nodeport_nat_ingress_ipv6             4448             5261      +813 (+18.28%)               234               247         +13 (+5.56%)
+bpf_xdp.o      tail_lb_ipv4                              71736            73442      +1706 (+2.38%)              4295              4370         +75 (+1.75%)
+-------------  ------------------------------  ---------------  ---------------  ------------------  ----------------  ----------------  -------------------
+
+P.S. To make Cilium ([0]) programs libbpf-compatible and thus
+veristat-loadable, apply changes from topmost commit in [1], which does
+minimal changes to Cilium source code, mostly around SEC() annotations
+and BPF map definitions.
+
+  [0] https://github.com/cilium/cilium/
+  [1] https://github.com/anakryiko/cilium/commits/libbpf-friendliness
+
+Fixes: b5dc0163d8fd ("bpf: precise scalar_value tracking")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/r/20221104163649.121784-2-andrii@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 4d62822f5502..30e0fa1bd83c 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -6992,6 +6992,11 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
+                               return err;
+                       return adjust_ptr_min_max_vals(env, insn,
+                                                      dst_reg, src_reg);
++              } else if (dst_reg->precise) {
++                      /* if dst_reg is precise, src_reg should be precise as well */
++                      err = mark_chain_precision(env, insn->src_reg);
++                      if (err)
++                              return err;
+               }
+       } else {
+               /* Pretend the src is a reg with a known value, since we only
+-- 
+2.35.1
+
diff --git a/queue-5.10/bpf-sockmap-fix-data-loss-caused-by-using-apply_byte.patch b/queue-5.10/bpf-sockmap-fix-data-loss-caused-by-using-apply_byte.patch
new file mode 100644 (file)
index 0000000..b702b75
--- /dev/null
@@ -0,0 +1,47 @@
+From dbe18f2cbaf35b9d673e7cc28ffa32267384b6d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 18:40:40 +0800
+Subject: bpf, sockmap: Fix data loss caused by using apply_bytes on ingress
+ redirect
+
+From: Pengcheng Yang <yangpc@wangsu.com>
+
+[ Upstream commit 9072931f020bfd907d6d89ee21ff1481cd78b407 ]
+
+Use apply_bytes on ingress redirect, when apply_bytes is less than
+the length of msg data, some data may be skipped and lost in
+bpf_tcp_ingress().
+
+If there is still data in the scatterlist that has not been consumed,
+we cannot move the msg iter.
+
+Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
+Signed-off-by: Pengcheng Yang <yangpc@wangsu.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/bpf/1669718441-2654-4-git-send-email-yangpc@wangsu.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_bpf.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index 027f7f9256e1..6a1685461f89 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -125,8 +125,11 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
+               tmp->sg.end = i;
+               if (apply) {
+                       apply_bytes -= size;
+-                      if (!apply_bytes)
++                      if (!apply_bytes) {
++                              if (sge->length)
++                                      sk_msg_iter_var_prev(i);
+                               break;
++                      }
+               }
+       } while (i != msg->sg.end);
+-- 
+2.35.1
+
diff --git a/queue-5.10/bpf-sockmap-fix-race-in-sock_map_free.patch b/queue-5.10/bpf-sockmap-fix-race-in-sock_map_free.patch
new file mode 100644 (file)
index 0000000..4f68150
--- /dev/null
@@ -0,0 +1,87 @@
+From e732a5fe95e5538c194b501022d722f5c7cc32eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 11:16:40 +0000
+Subject: bpf, sockmap: fix race in sock_map_free()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0a182f8d607464911756b4dbef5d6cad8de22469 ]
+
+sock_map_free() calls release_sock(sk) without owning a reference
+on the socket. This can cause use-after-free as syzbot found [1]
+
+Jakub Sitnicki already took care of a similar issue
+in sock_hash_free() in commit 75e68e5bf2c7 ("bpf, sockhash:
+Synchronize delete from bucket list on map free")
+
+[1]
+refcount_t: decrement hit 0; leaking memory.
+WARNING: CPU: 0 PID: 3785 at lib/refcount.c:31 refcount_warn_saturate+0x17c/0x1a0 lib/refcount.c:31
+Modules linked in:
+CPU: 0 PID: 3785 Comm: kworker/u4:6 Not tainted 6.1.0-rc7-syzkaller-00103-gef4d3ea40565 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022
+Workqueue: events_unbound bpf_map_free_deferred
+RIP: 0010:refcount_warn_saturate+0x17c/0x1a0 lib/refcount.c:31
+Code: 68 8b 31 c0 e8 75 71 15 fd 0f 0b e9 64 ff ff ff e8 d9 6e 4e fd c6 05 62 9c 3d 0a 01 48 c7 c7 80 bb 68 8b 31 c0 e8 54 71 15 fd <0f> 0b e9 43 ff ff ff 89 d9 80 e1 07 80 c1 03 38 c1 0f 8c a2 fe ff
+RSP: 0018:ffffc9000456fb60 EFLAGS: 00010246
+RAX: eae59bab72dcd700 RBX: 0000000000000004 RCX: ffff8880207057c0
+RDX: 0000000000000000 RSI: 0000000000000201 RDI: 0000000000000000
+RBP: 0000000000000004 R08: ffffffff816fdabd R09: fffff520008adee5
+R10: fffff520008adee5 R11: 1ffff920008adee4 R12: 0000000000000004
+R13: dffffc0000000000 R14: ffff88807b1c6c00 R15: 1ffff1100f638dcf
+FS: 0000000000000000(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000001b30c30000 CR3: 000000000d08e000 CR4: 00000000003506f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+<TASK>
+__refcount_dec include/linux/refcount.h:344 [inline]
+refcount_dec include/linux/refcount.h:359 [inline]
+__sock_put include/net/sock.h:779 [inline]
+tcp_release_cb+0x2d0/0x360 net/ipv4/tcp_output.c:1092
+release_sock+0xaf/0x1c0 net/core/sock.c:3468
+sock_map_free+0x219/0x2c0 net/core/sock_map.c:356
+process_one_work+0x81c/0xd10 kernel/workqueue.c:2289
+worker_thread+0xb14/0x1330 kernel/workqueue.c:2436
+kthread+0x266/0x300 kernel/kthread.c:376
+ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306
+</TASK>
+
+Fixes: 7e81a3530206 ("bpf: Sockmap, ensure sock lock held during tear down")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Cc: Jakub Sitnicki <jakub@cloudflare.com>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Song Liu <songliubraving@fb.com>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20221202111640.2745533-1-edumazet@google.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_map.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index cbf4184fabc9..ee5d3f49b0b5 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -358,11 +358,13 @@ static void sock_map_free(struct bpf_map *map)
+               sk = xchg(psk, NULL);
+               if (sk) {
++                      sock_hold(sk);
+                       lock_sock(sk);
+                       rcu_read_lock();
+                       sock_map_unref(sk, psk);
+                       rcu_read_unlock();
+                       release_sock(sk);
++                      sock_put(sk);
+               }
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/bpf-sockmap-fix-repeated-calls-to-sock_put-when-msg-.patch b/queue-5.10/bpf-sockmap-fix-repeated-calls-to-sock_put-when-msg-.patch
new file mode 100644 (file)
index 0000000..2a47ca8
--- /dev/null
@@ -0,0 +1,80 @@
+From 40aae9b3ece957c041cc1b4c83740934b8a61e2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 18:40:38 +0800
+Subject: bpf, sockmap: Fix repeated calls to sock_put() when msg has more_data
+
+From: Pengcheng Yang <yangpc@wangsu.com>
+
+[ Upstream commit 7a9841ca025275b5b0edfb0b618934abb6ceec15 ]
+
+In tcp_bpf_send_verdict() redirection, the eval variable is assigned to
+__SK_REDIRECT after the apply_bytes data is sent, if msg has more_data,
+sock_put() will be called multiple times.
+
+We should reset the eval variable to __SK_NONE every time more_data
+starts.
+
+This causes:
+
+IPv4: Attempt to release TCP socket in state 1 00000000b4c925d7
+------------[ cut here ]------------
+refcount_t: addition on 0; use-after-free.
+WARNING: CPU: 5 PID: 4482 at lib/refcount.c:25 refcount_warn_saturate+0x7d/0x110
+Modules linked in:
+CPU: 5 PID: 4482 Comm: sockhash_bypass Kdump: loaded Not tainted 6.0.0 #1
+Hardware name: Red Hat KVM, BIOS 1.11.0-2.el7 04/01/2014
+Call Trace:
+ <TASK>
+ __tcp_transmit_skb+0xa1b/0xb90
+ ? __alloc_skb+0x8c/0x1a0
+ ? __kmalloc_node_track_caller+0x184/0x320
+ tcp_write_xmit+0x22a/0x1110
+ __tcp_push_pending_frames+0x32/0xf0
+ do_tcp_sendpages+0x62d/0x640
+ tcp_bpf_push+0xae/0x2c0
+ tcp_bpf_sendmsg_redir+0x260/0x410
+ ? preempt_count_add+0x70/0xa0
+ tcp_bpf_send_verdict+0x386/0x4b0
+ tcp_bpf_sendmsg+0x21b/0x3b0
+ sock_sendmsg+0x58/0x70
+ __sys_sendto+0xfa/0x170
+ ? xfd_validate_state+0x1d/0x80
+ ? switch_fpu_return+0x59/0xe0
+ __x64_sys_sendto+0x24/0x30
+ do_syscall_64+0x37/0x90
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Fixes: cd9733f5d75c ("tcp_bpf: Fix one concurrency problem in the tcp_bpf_send_verdict function")
+Signed-off-by: Pengcheng Yang <yangpc@wangsu.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/bpf/1669718441-2654-2-git-send-email-yangpc@wangsu.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_bpf.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index 809ee0f32d59..027f7f9256e1 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -316,7 +316,7 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
+       bool cork = false, enospc = sk_msg_full(msg);
+       struct sock *sk_redir;
+       u32 tosend, origsize, sent, delta = 0;
+-      u32 eval = __SK_NONE;
++      u32 eval;
+       int ret;
+ more_data:
+@@ -347,6 +347,7 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
+       tosend = msg->sg.size;
+       if (psock->apply_bytes && psock->apply_bytes < tosend)
+               tosend = psock->apply_bytes;
++      eval = __SK_NONE;
+       switch (psock->eval) {
+       case __SK_PASS:
+-- 
+2.35.1
+
diff --git a/queue-5.10/brcmfmac-return-error-when-getting-invalid-max_flowr.patch b/queue-5.10/brcmfmac-return-error-when-getting-invalid-max_flowr.patch
new file mode 100644 (file)
index 0000000..fe5ab0f
--- /dev/null
@@ -0,0 +1,43 @@
+From 61721e65c6d8a0915e5e23a9a313b3387f36c8ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Sep 2022 22:10:00 -0500
+Subject: brcmfmac: return error when getting invalid max_flowrings from dongle
+
+From: Wright Feng <wright.feng@cypress.com>
+
+[ Upstream commit 2aca4f3734bd717e04943ddf340d49ab62299a00 ]
+
+When firmware hit trap at initialization, host will read abnormal
+max_flowrings number from dongle, and it will cause kernel panic when
+doing iowrite to initialize dongle ring.
+To detect this error at early stage, we directly return error when getting
+invalid max_flowrings(>256).
+
+Signed-off-by: Wright Feng <wright.feng@cypress.com>
+Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
+Signed-off-by: Ian Lin <ian.lin@infineon.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220929031001.9962-3-ian.lin@infineon.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+index 4e9d2b3659f0..6a5621f17bf5 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -1109,6 +1109,10 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
+                               BRCMF_NROF_H2D_COMMON_MSGRINGS;
+               max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS;
+       }
++      if (max_flowrings > 256) {
++              brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings);
++              return -EIO;
++      }
+       if (devinfo->dma_idx_sz != 0) {
+               bufsz = (max_submissionrings + max_completionrings) *
+-- 
+2.35.1
+
diff --git a/queue-5.10/can-kvaser_usb-add-struct-kvaser_usb_busparams.patch b/queue-5.10/can-kvaser_usb-add-struct-kvaser_usb_busparams.patch
new file mode 100644 (file)
index 0000000..cc20edc
--- /dev/null
@@ -0,0 +1,143 @@
+From 1f25bdff28529c25bb3f7e37c1d5d5b0420d33be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 20:52:36 +0200
+Subject: can: kvaser_usb: Add struct kvaser_usb_busparams
+
+From: Jimmy Assarsson <extja@kvaser.com>
+
+[ Upstream commit 00e5786177649c1e3110f9454fdd34e336597265 ]
+
+Add struct kvaser_usb_busparams containing the busparameters used in
+CMD_{SET,GET}_BUSPARAMS* commands.
+
+Tested-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://lore.kernel.org/all/20221010185237.319219-11-extja@kvaser.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Stable-dep-of: 39d3df6b0ea8 ("can: kvaser_usb: Compare requested bittiming parameters with actual parameters in do_set_{,data}_bittiming")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb.h   |  8 +++++
+ .../net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 32 +++++++------------
+ .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c  | 18 ++++-------
+ 3 files changed, 27 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+index 1f4583f1dae2..cb8018723748 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+@@ -76,6 +76,14 @@ struct kvaser_usb_tx_urb_context {
+       int dlc;
+ };
++struct kvaser_usb_busparams {
++      __le32 bitrate;
++      u8 tseg1;
++      u8 tseg2;
++      u8 sjw;
++      u8 nsamples;
++} __packed;
++
+ struct kvaser_usb {
+       struct usb_device *udev;
+       struct usb_interface *intf;
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index 9588efbfae71..72c37dc50b6b 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -193,17 +193,9 @@ struct kvaser_cmd_chip_state_event {
+ #define KVASER_USB_HYDRA_BUS_MODE_CANFD_ISO   0x01
+ #define KVASER_USB_HYDRA_BUS_MODE_NONISO      0x02
+ struct kvaser_cmd_set_busparams {
+-      __le32 bitrate;
+-      u8 tseg1;
+-      u8 tseg2;
+-      u8 sjw;
+-      u8 nsamples;
++      struct kvaser_usb_busparams busparams_arb;
+       u8 reserved0[4];
+-      __le32 bitrate_d;
+-      u8 tseg1_d;
+-      u8 tseg2_d;
+-      u8 sjw_d;
+-      u8 nsamples_d;
++      struct kvaser_usb_busparams busparams_data;
+       u8 canfd_mode;
+       u8 reserved1[7];
+ } __packed;
+@@ -1515,11 +1507,11 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
+               return -ENOMEM;
+       cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ;
+-      cmd->set_busparams_req.bitrate = cpu_to_le32(bt->bitrate);
+-      cmd->set_busparams_req.sjw = (u8)sjw;
+-      cmd->set_busparams_req.tseg1 = (u8)tseg1;
+-      cmd->set_busparams_req.tseg2 = (u8)tseg2;
+-      cmd->set_busparams_req.nsamples = 1;
++      cmd->set_busparams_req.busparams_arb.bitrate = cpu_to_le32(bt->bitrate);
++      cmd->set_busparams_req.busparams_arb.sjw = (u8)sjw;
++      cmd->set_busparams_req.busparams_arb.tseg1 = (u8)tseg1;
++      cmd->set_busparams_req.busparams_arb.tseg2 = (u8)tseg2;
++      cmd->set_busparams_req.busparams_arb.nsamples = 1;
+       kvaser_usb_hydra_set_cmd_dest_he
+               (cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
+@@ -1549,11 +1541,11 @@ static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev)
+               return -ENOMEM;
+       cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ;
+-      cmd->set_busparams_req.bitrate_d = cpu_to_le32(dbt->bitrate);
+-      cmd->set_busparams_req.sjw_d = (u8)sjw;
+-      cmd->set_busparams_req.tseg1_d = (u8)tseg1;
+-      cmd->set_busparams_req.tseg2_d = (u8)tseg2;
+-      cmd->set_busparams_req.nsamples_d = 1;
++      cmd->set_busparams_req.busparams_data.bitrate = cpu_to_le32(dbt->bitrate);
++      cmd->set_busparams_req.busparams_data.sjw = (u8)sjw;
++      cmd->set_busparams_req.busparams_data.tseg1 = (u8)tseg1;
++      cmd->set_busparams_req.busparams_data.tseg2 = (u8)tseg2;
++      cmd->set_busparams_req.busparams_data.nsamples = 1;
+       if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
+               if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index d1877ff2ff71..1e2f727a1efb 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -163,11 +163,7 @@ struct usbcan_cmd_softinfo {
+ struct kvaser_cmd_busparams {
+       u8 tid;
+       u8 channel;
+-      __le32 bitrate;
+-      u8 tseg1;
+-      u8 tseg2;
+-      u8 sjw;
+-      u8 no_samp;
++      struct kvaser_usb_busparams busparams;
+ } __packed;
+ struct kvaser_cmd_tx_can {
+@@ -1703,15 +1699,15 @@ static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
+       cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_busparams);
+       cmd->u.busparams.channel = priv->channel;
+       cmd->u.busparams.tid = 0xff;
+-      cmd->u.busparams.bitrate = cpu_to_le32(bt->bitrate);
+-      cmd->u.busparams.sjw = bt->sjw;
+-      cmd->u.busparams.tseg1 = bt->prop_seg + bt->phase_seg1;
+-      cmd->u.busparams.tseg2 = bt->phase_seg2;
++      cmd->u.busparams.busparams.bitrate = cpu_to_le32(bt->bitrate);
++      cmd->u.busparams.busparams.sjw = bt->sjw;
++      cmd->u.busparams.busparams.tseg1 = bt->prop_seg + bt->phase_seg1;
++      cmd->u.busparams.busparams.tseg2 = bt->phase_seg2;
+       if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+-              cmd->u.busparams.no_samp = 3;
++              cmd->u.busparams.busparams.nsamples = 3;
+       else
+-              cmd->u.busparams.no_samp = 1;
++              cmd->u.busparams.busparams.nsamples = 1;
+       rc = kvaser_usb_send_cmd(dev, cmd, cmd->len);
+-- 
+2.35.1
+
diff --git a/queue-5.10/can-kvaser_usb-compare-requested-bittiming-parameter.patch b/queue-5.10/can-kvaser_usb-compare-requested-bittiming-parameter.patch
new file mode 100644 (file)
index 0000000..8d317df
--- /dev/null
@@ -0,0 +1,598 @@
+From 92d0305d56b18757ef2d54713fae0474741cfa1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 20:52:37 +0200
+Subject: can: kvaser_usb: Compare requested bittiming parameters with actual
+ parameters in do_set_{,data}_bittiming
+
+From: Jimmy Assarsson <extja@kvaser.com>
+
+[ Upstream commit 39d3df6b0ea80f9b515c632ca07b39b1c156edee ]
+
+The device will respond with a CMD_ERROR_EVENT command, with error_code
+KVASER_USB_{LEAF,HYDRA}_ERROR_EVENT_PARAM, if the CMD_SET_BUSPARAMS_REQ
+contains invalid bittiming parameters.
+However, this command does not contain any channel reference.
+
+To check if the CMD_SET_BUSPARAMS_REQ was successful, redback and compare
+the requested bittiming parameters with the device reported parameters.
+
+Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices")
+Fixes: aec5fb2268b7 ("can: kvaser_usb: Add support for Kvaser USB hydra family")
+Tested-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Co-developed-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://lore.kernel.org/all/20221010185237.319219-12-extja@kvaser.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb.h   |  15 +-
+ .../net/can/usb/kvaser_usb/kvaser_usb_core.c  |  96 ++++++++++-
+ .../net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 150 +++++++++++++++---
+ .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c  |  64 ++++++--
+ 4 files changed, 284 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+index cb8018723748..5699531f8787 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+@@ -119,9 +119,12 @@ struct kvaser_usb_net_priv {
+       struct net_device *netdev;
+       int channel;
+-      struct completion start_comp, stop_comp, flush_comp;
++      struct completion start_comp, stop_comp, flush_comp,
++                        get_busparams_comp;
+       struct usb_anchor tx_submitted;
++      struct kvaser_usb_busparams busparams_nominal, busparams_data;
++
+       spinlock_t tx_contexts_lock; /* lock for active_tx_contexts */
+       int active_tx_contexts;
+       struct kvaser_usb_tx_urb_context tx_contexts[];
+@@ -131,7 +134,9 @@ struct kvaser_usb_net_priv {
+  * struct kvaser_usb_dev_ops - Device specific functions
+  * @dev_set_mode:             used for can.do_set_mode
+  * @dev_set_bittiming:                used for can.do_set_bittiming
++ * @dev_get_busparams:                readback arbitration busparams
+  * @dev_set_data_bittiming:   used for can.do_set_data_bittiming
++ * @dev_get_data_busparams:   readback data busparams
+  * @dev_get_berr_counter:     used for can.do_get_berr_counter
+  *
+  * @dev_setup_endpoints:      setup USB in and out endpoints
+@@ -153,8 +158,12 @@ struct kvaser_usb_net_priv {
+  */
+ struct kvaser_usb_dev_ops {
+       int (*dev_set_mode)(struct net_device *netdev, enum can_mode mode);
+-      int (*dev_set_bittiming)(struct net_device *netdev);
+-      int (*dev_set_data_bittiming)(struct net_device *netdev);
++      int (*dev_set_bittiming)(const struct net_device *netdev,
++                               const struct kvaser_usb_busparams *busparams);
++      int (*dev_get_busparams)(struct kvaser_usb_net_priv *priv);
++      int (*dev_set_data_bittiming)(const struct net_device *netdev,
++                                    const struct kvaser_usb_busparams *busparams);
++      int (*dev_get_data_busparams)(struct kvaser_usb_net_priv *priv);
+       int (*dev_get_berr_counter)(const struct net_device *netdev,
+                                   struct can_berr_counter *bec);
+       int (*dev_setup_endpoints)(struct kvaser_usb *dev);
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+index 2c816d8929da..1f015b496a47 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+@@ -416,10 +416,6 @@ static int kvaser_usb_open(struct net_device *netdev)
+       if (err)
+               return err;
+-      err = kvaser_usb_setup_rx_urbs(dev);
+-      if (err)
+-              goto error;
+-
+       err = ops->dev_set_opt_mode(priv);
+       if (err)
+               goto error;
+@@ -510,6 +506,93 @@ static int kvaser_usb_close(struct net_device *netdev)
+       return 0;
+ }
++static int kvaser_usb_set_bittiming(struct net_device *netdev)
++{
++      struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
++      struct kvaser_usb *dev = priv->dev;
++      const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
++      struct can_bittiming *bt = &priv->can.bittiming;
++
++      struct kvaser_usb_busparams busparams;
++      int tseg1 = bt->prop_seg + bt->phase_seg1;
++      int tseg2 = bt->phase_seg2;
++      int sjw = bt->sjw;
++      int err = -EOPNOTSUPP;
++
++      busparams.bitrate = cpu_to_le32(bt->bitrate);
++      busparams.sjw = (u8)sjw;
++      busparams.tseg1 = (u8)tseg1;
++      busparams.tseg2 = (u8)tseg2;
++      if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
++              busparams.nsamples = 3;
++      else
++              busparams.nsamples = 1;
++
++      err = ops->dev_set_bittiming(netdev, &busparams);
++      if (err)
++              return err;
++
++      err = kvaser_usb_setup_rx_urbs(priv->dev);
++      if (err)
++              return err;
++
++      err = ops->dev_get_busparams(priv);
++      if (err) {
++              /* Treat EOPNOTSUPP as success */
++              if (err == -EOPNOTSUPP)
++                      err = 0;
++              return err;
++      }
++
++      if (memcmp(&busparams, &priv->busparams_nominal,
++                 sizeof(priv->busparams_nominal)) != 0)
++              err = -EINVAL;
++
++      return err;
++}
++
++static int kvaser_usb_set_data_bittiming(struct net_device *netdev)
++{
++      struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
++      struct kvaser_usb *dev = priv->dev;
++      const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
++      struct can_bittiming *dbt = &priv->can.data_bittiming;
++
++      struct kvaser_usb_busparams busparams;
++      int tseg1 = dbt->prop_seg + dbt->phase_seg1;
++      int tseg2 = dbt->phase_seg2;
++      int sjw = dbt->sjw;
++      int err;
++
++      if (!ops->dev_set_data_bittiming ||
++          !ops->dev_get_data_busparams)
++              return -EOPNOTSUPP;
++
++      busparams.bitrate = cpu_to_le32(dbt->bitrate);
++      busparams.sjw = (u8)sjw;
++      busparams.tseg1 = (u8)tseg1;
++      busparams.tseg2 = (u8)tseg2;
++      busparams.nsamples = 1;
++
++      err = ops->dev_set_data_bittiming(netdev, &busparams);
++      if (err)
++              return err;
++
++      err = kvaser_usb_setup_rx_urbs(priv->dev);
++      if (err)
++              return err;
++
++      err = ops->dev_get_data_busparams(priv);
++      if (err)
++              return err;
++
++      if (memcmp(&busparams, &priv->busparams_data,
++                 sizeof(priv->busparams_data)) != 0)
++              err = -EINVAL;
++
++      return err;
++}
++
+ static void kvaser_usb_write_bulk_callback(struct urb *urb)
+ {
+       struct kvaser_usb_tx_urb_context *context = urb->context;
+@@ -695,6 +778,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+       init_completion(&priv->start_comp);
+       init_completion(&priv->stop_comp);
+       init_completion(&priv->flush_comp);
++      init_completion(&priv->get_busparams_comp);
+       priv->can.ctrlmode_supported = 0;
+       priv->dev = dev;
+@@ -707,7 +791,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+       priv->can.state = CAN_STATE_STOPPED;
+       priv->can.clock.freq = dev->cfg->clock.freq;
+       priv->can.bittiming_const = dev->cfg->bittiming_const;
+-      priv->can.do_set_bittiming = ops->dev_set_bittiming;
++      priv->can.do_set_bittiming = kvaser_usb_set_bittiming;
+       priv->can.do_set_mode = ops->dev_set_mode;
+       if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) ||
+           (priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP))
+@@ -719,7 +803,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+       if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) {
+               priv->can.data_bittiming_const = dev->cfg->data_bittiming_const;
+-              priv->can.do_set_data_bittiming = ops->dev_set_data_bittiming;
++              priv->can.do_set_data_bittiming = kvaser_usb_set_data_bittiming;
+       }
+       netdev->flags |= IFF_ECHO;
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index 72c37dc50b6b..2764fdd7e84b 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -43,6 +43,8 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc;
+ /* Minihydra command IDs */
+ #define CMD_SET_BUSPARAMS_REQ                 16
++#define CMD_GET_BUSPARAMS_REQ                 17
++#define CMD_GET_BUSPARAMS_RESP                        18
+ #define CMD_GET_CHIP_STATE_REQ                        19
+ #define CMD_CHIP_STATE_EVENT                  20
+ #define CMD_SET_DRIVERMODE_REQ                        21
+@@ -193,13 +195,26 @@ struct kvaser_cmd_chip_state_event {
+ #define KVASER_USB_HYDRA_BUS_MODE_CANFD_ISO   0x01
+ #define KVASER_USB_HYDRA_BUS_MODE_NONISO      0x02
+ struct kvaser_cmd_set_busparams {
+-      struct kvaser_usb_busparams busparams_arb;
++      struct kvaser_usb_busparams busparams_nominal;
+       u8 reserved0[4];
+       struct kvaser_usb_busparams busparams_data;
+       u8 canfd_mode;
+       u8 reserved1[7];
+ } __packed;
++/* Busparam type */
++#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN    0x00
++#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD  0x01
++struct kvaser_cmd_get_busparams_req {
++      u8 type;
++      u8 reserved[27];
++} __packed;
++
++struct kvaser_cmd_get_busparams_res {
++      struct kvaser_usb_busparams busparams;
++      u8 reserved[20];
++} __packed;
++
+ /* Ctrl modes */
+ #define KVASER_USB_HYDRA_CTRLMODE_NORMAL      0x01
+ #define KVASER_USB_HYDRA_CTRLMODE_LISTEN      0x02
+@@ -270,6 +285,8 @@ struct kvaser_cmd {
+               struct kvaser_cmd_error_event error_event;
+               struct kvaser_cmd_set_busparams set_busparams_req;
++              struct kvaser_cmd_get_busparams_req get_busparams_req;
++              struct kvaser_cmd_get_busparams_res get_busparams_res;
+               struct kvaser_cmd_chip_state_event chip_state_event;
+@@ -352,6 +369,10 @@ struct kvaser_cmd_ext {
+       } __packed;
+ } __packed;
++struct kvaser_usb_net_hydra_priv {
++      int pending_get_busparams_type;
++};
++
+ static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = {
+       .name = "kvaser_usb_kcan",
+       .tseg1_min = 1,
+@@ -805,6 +826,39 @@ static void kvaser_usb_hydra_flush_queue_reply(const struct kvaser_usb *dev,
+       complete(&priv->flush_comp);
+ }
++static void kvaser_usb_hydra_get_busparams_reply(const struct kvaser_usb *dev,
++                                               const struct kvaser_cmd *cmd)
++{
++      struct kvaser_usb_net_priv *priv;
++      struct kvaser_usb_net_hydra_priv *hydra;
++
++      priv = kvaser_usb_hydra_net_priv_from_cmd(dev, cmd);
++      if (!priv)
++              return;
++
++      hydra = priv->sub_priv;
++      if (!hydra)
++              return;
++
++      switch (hydra->pending_get_busparams_type) {
++      case KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN:
++              memcpy(&priv->busparams_nominal, &cmd->get_busparams_res.busparams,
++                     sizeof(priv->busparams_nominal));
++              break;
++      case KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD:
++              memcpy(&priv->busparams_data, &cmd->get_busparams_res.busparams,
++                     sizeof(priv->busparams_nominal));
++              break;
++      default:
++              dev_warn(&dev->intf->dev, "Unknown get_busparams_type %d\n",
++                       hydra->pending_get_busparams_type);
++              break;
++      }
++      hydra->pending_get_busparams_type = -1;
++
++      complete(&priv->get_busparams_comp);
++}
++
+ static void
+ kvaser_usb_hydra_bus_status_to_can_state(const struct kvaser_usb_net_priv *priv,
+                                        u8 bus_status,
+@@ -1291,6 +1345,10 @@ static void kvaser_usb_hydra_handle_cmd_std(const struct kvaser_usb *dev,
+               kvaser_usb_hydra_state_event(dev, cmd);
+               break;
++      case CMD_GET_BUSPARAMS_RESP:
++              kvaser_usb_hydra_get_busparams_reply(dev, cmd);
++              break;
++
+       case CMD_ERROR_EVENT:
+               kvaser_usb_hydra_error_event(dev, cmd);
+               break;
+@@ -1491,15 +1549,58 @@ static int kvaser_usb_hydra_set_mode(struct net_device *netdev,
+       return err;
+ }
+-static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
++static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv,
++                                        int busparams_type)
++{
++      struct kvaser_usb *dev = priv->dev;
++      struct kvaser_usb_net_hydra_priv *hydra = priv->sub_priv;
++      struct kvaser_cmd *cmd;
++      int err;
++
++      if (!hydra)
++              return -EINVAL;
++
++      cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
++      if (!cmd)
++              return -ENOMEM;
++
++      cmd->header.cmd_no = CMD_GET_BUSPARAMS_REQ;
++      kvaser_usb_hydra_set_cmd_dest_he
++              (cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
++      kvaser_usb_hydra_set_cmd_transid
++                              (cmd, kvaser_usb_hydra_get_next_transid(dev));
++      cmd->get_busparams_req.type = busparams_type;
++      hydra->pending_get_busparams_type = busparams_type;
++
++      reinit_completion(&priv->get_busparams_comp);
++
++      err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
++      if (err)
++              return err;
++
++      if (!wait_for_completion_timeout(&priv->get_busparams_comp,
++                                       msecs_to_jiffies(KVASER_USB_TIMEOUT)))
++              return -ETIMEDOUT;
++
++      return err;
++}
++
++static int kvaser_usb_hydra_get_nominal_busparams(struct kvaser_usb_net_priv *priv)
++{
++      return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN);
++}
++
++static int kvaser_usb_hydra_get_data_busparams(struct kvaser_usb_net_priv *priv)
++{
++      return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD);
++}
++
++static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev,
++                                        const struct kvaser_usb_busparams *busparams)
+ {
+       struct kvaser_cmd *cmd;
+       struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+-      struct can_bittiming *bt = &priv->can.bittiming;
+       struct kvaser_usb *dev = priv->dev;
+-      int tseg1 = bt->prop_seg + bt->phase_seg1;
+-      int tseg2 = bt->phase_seg2;
+-      int sjw = bt->sjw;
+       int err;
+       cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
+@@ -1507,11 +1608,8 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
+               return -ENOMEM;
+       cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ;
+-      cmd->set_busparams_req.busparams_arb.bitrate = cpu_to_le32(bt->bitrate);
+-      cmd->set_busparams_req.busparams_arb.sjw = (u8)sjw;
+-      cmd->set_busparams_req.busparams_arb.tseg1 = (u8)tseg1;
+-      cmd->set_busparams_req.busparams_arb.tseg2 = (u8)tseg2;
+-      cmd->set_busparams_req.busparams_arb.nsamples = 1;
++      memcpy(&cmd->set_busparams_req.busparams_nominal, busparams,
++             sizeof(cmd->set_busparams_req.busparams_nominal));
+       kvaser_usb_hydra_set_cmd_dest_he
+               (cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
+@@ -1525,15 +1623,12 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
+       return err;
+ }
+-static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev)
++static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev,
++                                             const struct kvaser_usb_busparams *busparams)
+ {
+       struct kvaser_cmd *cmd;
+       struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+-      struct can_bittiming *dbt = &priv->can.data_bittiming;
+       struct kvaser_usb *dev = priv->dev;
+-      int tseg1 = dbt->prop_seg + dbt->phase_seg1;
+-      int tseg2 = dbt->phase_seg2;
+-      int sjw = dbt->sjw;
+       int err;
+       cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
+@@ -1541,11 +1636,8 @@ static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev)
+               return -ENOMEM;
+       cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ;
+-      cmd->set_busparams_req.busparams_data.bitrate = cpu_to_le32(dbt->bitrate);
+-      cmd->set_busparams_req.busparams_data.sjw = (u8)sjw;
+-      cmd->set_busparams_req.busparams_data.tseg1 = (u8)tseg1;
+-      cmd->set_busparams_req.busparams_data.tseg2 = (u8)tseg2;
+-      cmd->set_busparams_req.busparams_data.nsamples = 1;
++      memcpy(&cmd->set_busparams_req.busparams_data, busparams,
++             sizeof(cmd->set_busparams_req.busparams_data));
+       if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
+               if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)
+@@ -1652,6 +1744,19 @@ static int kvaser_usb_hydra_init_card(struct kvaser_usb *dev)
+       return 0;
+ }
++static int kvaser_usb_hydra_init_channel(struct kvaser_usb_net_priv *priv)
++{
++      struct kvaser_usb_net_hydra_priv *hydra;
++
++      hydra = devm_kzalloc(&priv->dev->intf->dev, sizeof(*hydra), GFP_KERNEL);
++      if (!hydra)
++              return -ENOMEM;
++
++      priv->sub_priv = hydra;
++
++      return 0;
++}
++
+ static int kvaser_usb_hydra_get_software_info(struct kvaser_usb *dev)
+ {
+       struct kvaser_cmd cmd;
+@@ -1994,10 +2099,13 @@ kvaser_usb_hydra_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
+ const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops = {
+       .dev_set_mode = kvaser_usb_hydra_set_mode,
+       .dev_set_bittiming = kvaser_usb_hydra_set_bittiming,
++      .dev_get_busparams = kvaser_usb_hydra_get_nominal_busparams,
+       .dev_set_data_bittiming = kvaser_usb_hydra_set_data_bittiming,
++      .dev_get_data_busparams = kvaser_usb_hydra_get_data_busparams,
+       .dev_get_berr_counter = kvaser_usb_hydra_get_berr_counter,
+       .dev_setup_endpoints = kvaser_usb_hydra_setup_endpoints,
+       .dev_init_card = kvaser_usb_hydra_init_card,
++      .dev_init_channel = kvaser_usb_hydra_init_channel,
+       .dev_get_software_info = kvaser_usb_hydra_get_software_info,
+       .dev_get_software_details = kvaser_usb_hydra_get_software_details,
+       .dev_get_card_info = kvaser_usb_hydra_get_card_info,
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 1e2f727a1efb..f06d63db9077 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -56,6 +56,8 @@
+ #define CMD_RX_EXT_MESSAGE            14
+ #define CMD_TX_EXT_MESSAGE            15
+ #define CMD_SET_BUS_PARAMS            16
++#define CMD_GET_BUS_PARAMS            17
++#define CMD_GET_BUS_PARAMS_REPLY      18
+ #define CMD_GET_CHIP_STATE            19
+ #define CMD_CHIP_STATE_EVENT          20
+ #define CMD_SET_CTRL_MODE             21
+@@ -375,6 +377,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = {
+       [CMD_CHIP_STATE_EVENT]          = kvaser_fsize(u.leaf.chip_state_event),
+       [CMD_CAN_ERROR_EVENT]           = kvaser_fsize(u.leaf.can_error_event),
+       [CMD_GET_CAPABILITIES_RESP]     = kvaser_fsize(u.leaf.cap_res),
++      [CMD_GET_BUS_PARAMS_REPLY]      = kvaser_fsize(u.busparams),
+       [CMD_ERROR_EVENT]               = kvaser_fsize(u.leaf.error_event),
+       /* ignored events: */
+       [CMD_FLUSH_QUEUE_REPLY]         = CMD_SIZE_ANY,
+@@ -1467,6 +1470,25 @@ static void kvaser_usb_leaf_stop_chip_reply(const struct kvaser_usb *dev,
+       complete(&priv->stop_comp);
+ }
++static void kvaser_usb_leaf_get_busparams_reply(const struct kvaser_usb *dev,
++                                              const struct kvaser_cmd *cmd)
++{
++      struct kvaser_usb_net_priv *priv;
++      u8 channel = cmd->u.busparams.channel;
++
++      if (channel >= dev->nchannels) {
++              dev_err(&dev->intf->dev,
++                      "Invalid channel number (%d)\n", channel);
++              return;
++      }
++
++      priv = dev->nets[channel];
++      memcpy(&priv->busparams_nominal, &cmd->u.busparams.busparams,
++             sizeof(priv->busparams_nominal));
++
++      complete(&priv->get_busparams_comp);
++}
++
+ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
+                                          const struct kvaser_cmd *cmd)
+ {
+@@ -1509,6 +1531,10 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
+               kvaser_usb_leaf_error_event(dev, cmd);
+               break;
++      case CMD_GET_BUS_PARAMS_REPLY:
++              kvaser_usb_leaf_get_busparams_reply(dev, cmd);
++              break;
++
+       /* Ignored commands */
+       case CMD_USBCAN_CLOCK_OVERFLOW_EVENT:
+               if (dev->driver_info->family != KVASER_USBCAN)
+@@ -1683,10 +1709,10 @@ static void kvaser_usb_leaf_remove_channel(struct kvaser_usb_net_priv *priv)
+               cancel_delayed_work_sync(&leaf->chip_state_req_work);
+ }
+-static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
++static int kvaser_usb_leaf_set_bittiming(const struct net_device *netdev,
++                                       const struct kvaser_usb_busparams *busparams)
+ {
+       struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+-      struct can_bittiming *bt = &priv->can.bittiming;
+       struct kvaser_usb *dev = priv->dev;
+       struct kvaser_cmd *cmd;
+       int rc;
+@@ -1699,15 +1725,8 @@ static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
+       cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_busparams);
+       cmd->u.busparams.channel = priv->channel;
+       cmd->u.busparams.tid = 0xff;
+-      cmd->u.busparams.busparams.bitrate = cpu_to_le32(bt->bitrate);
+-      cmd->u.busparams.busparams.sjw = bt->sjw;
+-      cmd->u.busparams.busparams.tseg1 = bt->prop_seg + bt->phase_seg1;
+-      cmd->u.busparams.busparams.tseg2 = bt->phase_seg2;
+-
+-      if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+-              cmd->u.busparams.busparams.nsamples = 3;
+-      else
+-              cmd->u.busparams.busparams.nsamples = 1;
++      memcpy(&cmd->u.busparams.busparams, busparams,
++             sizeof(cmd->u.busparams.busparams));
+       rc = kvaser_usb_send_cmd(dev, cmd, cmd->len);
+@@ -1715,6 +1734,27 @@ static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
+       return rc;
+ }
++static int kvaser_usb_leaf_get_busparams(struct kvaser_usb_net_priv *priv)
++{
++      int err;
++
++      if (priv->dev->driver_info->family == KVASER_USBCAN)
++              return -EOPNOTSUPP;
++
++      reinit_completion(&priv->get_busparams_comp);
++
++      err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_GET_BUS_PARAMS,
++                                            priv->channel);
++      if (err)
++              return err;
++
++      if (!wait_for_completion_timeout(&priv->get_busparams_comp,
++                                       msecs_to_jiffies(KVASER_USB_TIMEOUT)))
++              return -ETIMEDOUT;
++
++      return 0;
++}
++
+ static int kvaser_usb_leaf_set_mode(struct net_device *netdev,
+                                   enum can_mode mode)
+ {
+@@ -1776,7 +1816,9 @@ static int kvaser_usb_leaf_setup_endpoints(struct kvaser_usb *dev)
+ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = {
+       .dev_set_mode = kvaser_usb_leaf_set_mode,
+       .dev_set_bittiming = kvaser_usb_leaf_set_bittiming,
++      .dev_get_busparams = kvaser_usb_leaf_get_busparams,
+       .dev_set_data_bittiming = NULL,
++      .dev_get_data_busparams = NULL,
+       .dev_get_berr_counter = kvaser_usb_leaf_get_berr_counter,
+       .dev_setup_endpoints = kvaser_usb_leaf_setup_endpoints,
+       .dev_init_card = kvaser_usb_leaf_init_card,
+-- 
+2.35.1
+
diff --git a/queue-5.10/can-kvaser_usb-do-not-increase-tx-statistics-when-se.patch b/queue-5.10/can-kvaser_usb-do-not-increase-tx-statistics-when-se.patch
new file mode 100644 (file)
index 0000000..502b628
--- /dev/null
@@ -0,0 +1,76 @@
+From 719eb15056fdef2f8246f173092142a957335193 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Dec 2021 21:15:28 +0900
+Subject: can: kvaser_usb: do not increase tx statistics when sending error
+ message frames
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 0b0ce2c67795672115ac6ca28351a78799cd114b ]
+
+The CAN error message frames (i.e. error skb) are an interface
+specific to socket CAN. The payload of the CAN error message frames
+does not correspond to any actual data sent on the wire. Only an error
+flag and a delimiter are transmitted when an error occurs (c.f. ISO
+11898-1 section 10.4.4.2 "Error flag").
+
+For this reason, it makes no sense to increment the tx_packets and
+tx_bytes fields of struct net_device_stats when sending an error
+message frame because no actual payload will be transmitted on the
+wire.
+
+N.B. Sending error message frames is a very specific feature which, at
+the moment, is only supported by the Kvaser Hydra hardware. Please
+refer to [1] for more details on the topic.
+
+[1] https://lore.kernel.org/linux-can/CAMZ6RqK0rTNg3u3mBpZOoY51jLZ-et-J01tY6-+mWsM4meVw-A@mail.gmail.com/t/#u
+
+Link: https://lore.kernel.org/all/20211207121531.42941-3-mailhol.vincent@wanadoo.fr
+Co-developed-by: Jimmy Assarsson <extja@kvaser.com>
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Stable-dep-of: 35364f5b41a4 ("can: kvaser_usb: kvaser_usb_leaf: Get capabilities from device")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index 45d278724883..9588efbfae71 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -293,6 +293,7 @@ struct kvaser_cmd {
+ #define KVASER_USB_HYDRA_CF_FLAG_OVERRUN      BIT(1)
+ #define KVASER_USB_HYDRA_CF_FLAG_REMOTE_FRAME BIT(4)
+ #define KVASER_USB_HYDRA_CF_FLAG_EXTENDED_ID  BIT(5)
++#define KVASER_USB_HYDRA_CF_FLAG_TX_ACK               BIT(6)
+ /* CAN frame flags. Used in ext_rx_can and ext_tx_can */
+ #define KVASER_USB_HYDRA_CF_FLAG_OSM_NACK     BIT(12)
+ #define KVASER_USB_HYDRA_CF_FLAG_ABL          BIT(13)
+@@ -1099,6 +1100,7 @@ static void kvaser_usb_hydra_tx_acknowledge(const struct kvaser_usb *dev,
+       struct kvaser_usb_net_priv *priv;
+       unsigned long irq_flags;
+       bool one_shot_fail = false;
++      bool is_err_frame = false;
+       u16 transid = kvaser_usb_hydra_get_cmd_transid(cmd);
+       priv = kvaser_usb_hydra_net_priv_from_cmd(dev, cmd);
+@@ -1117,10 +1119,13 @@ static void kvaser_usb_hydra_tx_acknowledge(const struct kvaser_usb *dev,
+                       kvaser_usb_hydra_one_shot_fail(priv, cmd_ext);
+                       one_shot_fail = true;
+               }
++
++              is_err_frame = flags & KVASER_USB_HYDRA_CF_FLAG_TX_ACK &&
++                             flags & KVASER_USB_HYDRA_CF_FLAG_ERROR_FRAME;
+       }
+       context = &priv->tx_contexts[transid % dev->max_tx_urbs];
+-      if (!one_shot_fail) {
++      if (!one_shot_fail && !is_err_frame) {
+               struct net_device_stats *stats = &priv->netdev->stats;
+               stats->tx_packets++;
+-- 
+2.35.1
+
diff --git a/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-get-capabilities-from.patch b/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-get-capabilities-from.patch
new file mode 100644 (file)
index 0000000..6780c82
--- /dev/null
@@ -0,0 +1,231 @@
+From 3bcf7c8c2a5413ab7e5921cdc4010c3cb9e85dab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 20:52:28 +0200
+Subject: can: kvaser_usb: kvaser_usb_leaf: Get capabilities from device
+
+From: Jimmy Assarsson <extja@kvaser.com>
+
+[ Upstream commit 35364f5b41a4917fe94a3f393d149b63ec583297 ]
+
+Use the CMD_GET_CAPABILITIES_REQ command to query the device for certain
+capabilities. We are only interested in LISTENONLY mode and wither the
+device reports CAN error counters.
+
+Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices")
+Reported-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Tested-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://lore.kernel.org/all/20221010185237.319219-3-extja@kvaser.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c  | 144 +++++++++++++++++-
+ 1 file changed, 143 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 15380cc08ee6..26f32828f905 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -73,6 +73,8 @@
+ #define CMD_TX_ACKNOWLEDGE            50
+ #define CMD_CAN_ERROR_EVENT           51
+ #define CMD_FLUSH_QUEUE_REPLY         68
++#define CMD_GET_CAPABILITIES_REQ      95
++#define CMD_GET_CAPABILITIES_RESP     96
+ #define CMD_LEAF_LOG_MESSAGE          106
+@@ -82,6 +84,8 @@
+ #define KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK BIT(5)
+ #define KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK BIT(6)
++#define KVASER_USB_LEAF_SWOPTION_EXT_CAP BIT(12)
++
+ /* error factors */
+ #define M16C_EF_ACKE                  BIT(0)
+ #define M16C_EF_CRCE                  BIT(1)
+@@ -277,6 +281,28 @@ struct leaf_cmd_log_message {
+       u8 data[8];
+ } __packed;
++/* Sub commands for cap_req and cap_res */
++#define KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE 0x02
++#define KVASER_USB_LEAF_CAP_CMD_ERR_REPORT 0x05
++struct kvaser_cmd_cap_req {
++      __le16 padding0;
++      __le16 cap_cmd;
++      __le16 padding1;
++      __le16 channel;
++} __packed;
++
++/* Status codes for cap_res */
++#define KVASER_USB_LEAF_CAP_STAT_OK 0x00
++#define KVASER_USB_LEAF_CAP_STAT_NOT_IMPL 0x01
++#define KVASER_USB_LEAF_CAP_STAT_UNAVAIL 0x02
++struct kvaser_cmd_cap_res {
++      __le16 padding;
++      __le16 cap_cmd;
++      __le16 status;
++      __le32 mask;
++      __le32 value;
++} __packed;
++
+ struct kvaser_cmd {
+       u8 len;
+       u8 id;
+@@ -294,6 +320,8 @@ struct kvaser_cmd {
+                       struct leaf_cmd_chip_state_event chip_state_event;
+                       struct leaf_cmd_error_event error_event;
+                       struct leaf_cmd_log_message log_message;
++                      struct kvaser_cmd_cap_req cap_req;
++                      struct kvaser_cmd_cap_res cap_res;
+               } __packed leaf;
+               union {
+@@ -323,6 +351,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = {
+       [CMD_LEAF_LOG_MESSAGE]          = kvaser_fsize(u.leaf.log_message),
+       [CMD_CHIP_STATE_EVENT]          = kvaser_fsize(u.leaf.chip_state_event),
+       [CMD_CAN_ERROR_EVENT]           = kvaser_fsize(u.leaf.error_event),
++      [CMD_GET_CAPABILITIES_RESP]     = kvaser_fsize(u.leaf.cap_res),
+       /* ignored events: */
+       [CMD_FLUSH_QUEUE_REPLY]         = CMD_SIZE_ANY,
+ };
+@@ -607,6 +636,9 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev,
+       dev->fw_version = le32_to_cpu(softinfo->fw_version);
+       dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx);
++      if (sw_options & KVASER_USB_LEAF_SWOPTION_EXT_CAP)
++              dev->card_data.capabilities |= KVASER_USB_CAP_EXT_CAP;
++
+       if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) {
+               /* Firmware expects bittiming parameters calculated for 16MHz
+                * clock, regardless of the actual clock
+@@ -694,6 +726,116 @@ static int kvaser_usb_leaf_get_card_info(struct kvaser_usb *dev)
+       return 0;
+ }
++static int kvaser_usb_leaf_get_single_capability(struct kvaser_usb *dev,
++                                               u16 cap_cmd_req, u16 *status)
++{
++      struct kvaser_usb_dev_card_data *card_data = &dev->card_data;
++      struct kvaser_cmd *cmd;
++      u32 value = 0;
++      u32 mask = 0;
++      u16 cap_cmd_res;
++      int err;
++      int i;
++
++      cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
++      if (!cmd)
++              return -ENOMEM;
++
++      cmd->id = CMD_GET_CAPABILITIES_REQ;
++      cmd->u.leaf.cap_req.cap_cmd = cpu_to_le16(cap_cmd_req);
++      cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_cap_req);
++
++      err = kvaser_usb_send_cmd(dev, cmd, cmd->len);
++      if (err)
++              goto end;
++
++      err = kvaser_usb_leaf_wait_cmd(dev, CMD_GET_CAPABILITIES_RESP, cmd);
++      if (err)
++              goto end;
++
++      *status = le16_to_cpu(cmd->u.leaf.cap_res.status);
++
++      if (*status != KVASER_USB_LEAF_CAP_STAT_OK)
++              goto end;
++
++      cap_cmd_res = le16_to_cpu(cmd->u.leaf.cap_res.cap_cmd);
++      switch (cap_cmd_res) {
++      case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE:
++      case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT:
++              value = le32_to_cpu(cmd->u.leaf.cap_res.value);
++              mask = le32_to_cpu(cmd->u.leaf.cap_res.mask);
++              break;
++      default:
++              dev_warn(&dev->intf->dev, "Unknown capability command %u\n",
++                       cap_cmd_res);
++              break;
++      }
++
++      for (i = 0; i < dev->nchannels; i++) {
++              if (BIT(i) & (value & mask)) {
++                      switch (cap_cmd_res) {
++                      case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE:
++                              card_data->ctrlmode_supported |=
++                                              CAN_CTRLMODE_LISTENONLY;
++                              break;
++                      case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT:
++                              card_data->capabilities |=
++                                              KVASER_USB_CAP_BERR_CAP;
++                              break;
++                      }
++              }
++      }
++
++end:
++      kfree(cmd);
++
++      return err;
++}
++
++static int kvaser_usb_leaf_get_capabilities_leaf(struct kvaser_usb *dev)
++{
++      int err;
++      u16 status;
++
++      if (!(dev->card_data.capabilities & KVASER_USB_CAP_EXT_CAP)) {
++              dev_info(&dev->intf->dev,
++                       "No extended capability support. Upgrade device firmware.\n");
++              return 0;
++      }
++
++      err = kvaser_usb_leaf_get_single_capability(dev,
++                                                  KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE,
++                                                  &status);
++      if (err)
++              return err;
++      if (status)
++              dev_info(&dev->intf->dev,
++                       "KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE failed %u\n",
++                       status);
++
++      err = kvaser_usb_leaf_get_single_capability(dev,
++                                                  KVASER_USB_LEAF_CAP_CMD_ERR_REPORT,
++                                                  &status);
++      if (err)
++              return err;
++      if (status)
++              dev_info(&dev->intf->dev,
++                       "KVASER_USB_LEAF_CAP_CMD_ERR_REPORT failed %u\n",
++                       status);
++
++      return 0;
++}
++
++static int kvaser_usb_leaf_get_capabilities(struct kvaser_usb *dev)
++{
++      int err = 0;
++
++      if (dev->driver_info->family == KVASER_LEAF)
++              err = kvaser_usb_leaf_get_capabilities_leaf(dev);
++
++      return err;
++}
++
+ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev,
+                                          const struct kvaser_cmd *cmd)
+ {
+@@ -1490,7 +1632,7 @@ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = {
+       .dev_get_software_info = kvaser_usb_leaf_get_software_info,
+       .dev_get_software_details = NULL,
+       .dev_get_card_info = kvaser_usb_leaf_get_card_info,
+-      .dev_get_capabilities = NULL,
++      .dev_get_capabilities = kvaser_usb_leaf_get_capabilities,
+       .dev_set_opt_mode = kvaser_usb_leaf_set_opt_mode,
+       .dev_start_chip = kvaser_usb_leaf_start_chip,
+       .dev_stop_chip = kvaser_usb_leaf_stop_chip,
+-- 
+2.35.1
+
diff --git a/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-handle-cmd_error_even.patch b/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-handle-cmd_error_even.patch
new file mode 100644 (file)
index 0000000..a8b15b1
--- /dev/null
@@ -0,0 +1,186 @@
+From 8548322d35b082c0745d009d7dd8ca1be9d540ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 20:52:30 +0200
+Subject: can: kvaser_usb: kvaser_usb_leaf: Handle CMD_ERROR_EVENT
+
+From: Jimmy Assarsson <extja@kvaser.com>
+
+[ Upstream commit b24cb2d169e0c9dce664a959e1f2aa9781285dc9 ]
+
+The device will send an error event command, to indicate certain errors.
+This indicates a misbehaving driver, and should never occur.
+
+Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices")
+Tested-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Co-developed-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://lore.kernel.org/all/20221010185237.319219-5-extja@kvaser.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c  | 99 +++++++++++++++++++
+ 1 file changed, 99 insertions(+)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 4f3d1150b2b2..3c3e78992b55 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -69,6 +69,7 @@
+ #define CMD_GET_CARD_INFO_REPLY               35
+ #define CMD_GET_SOFTWARE_INFO         38
+ #define CMD_GET_SOFTWARE_INFO_REPLY   39
++#define CMD_ERROR_EVENT                       45
+ #define CMD_FLUSH_QUEUE                       48
+ #define CMD_TX_ACKNOWLEDGE            50
+ #define CMD_CAN_ERROR_EVENT           51
+@@ -257,6 +258,28 @@ struct usbcan_cmd_can_error_event {
+       __le16 time;
+ } __packed;
++/* CMD_ERROR_EVENT error codes */
++#define KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL 0x8
++#define KVASER_USB_LEAF_ERROR_EVENT_PARAM 0x9
++
++struct leaf_cmd_error_event {
++      u8 tid;
++      u8 error_code;
++      __le16 timestamp[3];
++      __le16 padding;
++      __le16 info1;
++      __le16 info2;
++} __packed;
++
++struct usbcan_cmd_error_event {
++      u8 tid;
++      u8 error_code;
++      __le16 info1;
++      __le16 info2;
++      __le16 timestamp;
++      __le16 padding;
++} __packed;
++
+ struct kvaser_cmd_ctrl_mode {
+       u8 tid;
+       u8 channel;
+@@ -320,6 +343,7 @@ struct kvaser_cmd {
+                       struct leaf_cmd_chip_state_event chip_state_event;
+                       struct leaf_cmd_can_error_event can_error_event;
+                       struct leaf_cmd_log_message log_message;
++                      struct leaf_cmd_error_event error_event;
+                       struct kvaser_cmd_cap_req cap_req;
+                       struct kvaser_cmd_cap_res cap_res;
+               } __packed leaf;
+@@ -329,6 +353,7 @@ struct kvaser_cmd {
+                       struct usbcan_cmd_rx_can rx_can;
+                       struct usbcan_cmd_chip_state_event chip_state_event;
+                       struct usbcan_cmd_can_error_event can_error_event;
++                      struct usbcan_cmd_error_event error_event;
+               } __packed usbcan;
+               struct kvaser_cmd_tx_can tx_can;
+@@ -352,6 +377,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = {
+       [CMD_CHIP_STATE_EVENT]          = kvaser_fsize(u.leaf.chip_state_event),
+       [CMD_CAN_ERROR_EVENT]           = kvaser_fsize(u.leaf.can_error_event),
+       [CMD_GET_CAPABILITIES_RESP]     = kvaser_fsize(u.leaf.cap_res),
++      [CMD_ERROR_EVENT]               = kvaser_fsize(u.leaf.error_event),
+       /* ignored events: */
+       [CMD_FLUSH_QUEUE_REPLY]         = CMD_SIZE_ANY,
+ };
+@@ -366,6 +392,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = {
+       [CMD_RX_EXT_MESSAGE]            = kvaser_fsize(u.usbcan.rx_can),
+       [CMD_CHIP_STATE_EVENT]          = kvaser_fsize(u.usbcan.chip_state_event),
+       [CMD_CAN_ERROR_EVENT]           = kvaser_fsize(u.usbcan.can_error_event),
++      [CMD_ERROR_EVENT]               = kvaser_fsize(u.usbcan.error_event),
+       /* ignored events: */
+       [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY,
+ };
+@@ -1308,6 +1335,74 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
+       netif_rx(skb);
+ }
++static void kvaser_usb_leaf_error_event_parameter(const struct kvaser_usb *dev,
++                                                const struct kvaser_cmd *cmd)
++{
++      u16 info1 = 0;
++
++      switch (dev->driver_info->family) {
++      case KVASER_LEAF:
++              info1 = le16_to_cpu(cmd->u.leaf.error_event.info1);
++              break;
++      case KVASER_USBCAN:
++              info1 = le16_to_cpu(cmd->u.usbcan.error_event.info1);
++              break;
++      }
++
++      /* info1 will contain the offending cmd_no */
++      switch (info1) {
++      case CMD_SET_CTRL_MODE:
++              dev_warn(&dev->intf->dev,
++                       "CMD_SET_CTRL_MODE error in parameter\n");
++              break;
++
++      case CMD_SET_BUS_PARAMS:
++              dev_warn(&dev->intf->dev,
++                       "CMD_SET_BUS_PARAMS error in parameter\n");
++              break;
++
++      default:
++              dev_warn(&dev->intf->dev,
++                       "Unhandled parameter error event cmd_no (%u)\n",
++                       info1);
++              break;
++      }
++}
++
++static void kvaser_usb_leaf_error_event(const struct kvaser_usb *dev,
++                                      const struct kvaser_cmd *cmd)
++{
++      u8 error_code = 0;
++
++      switch (dev->driver_info->family) {
++      case KVASER_LEAF:
++              error_code = cmd->u.leaf.error_event.error_code;
++              break;
++      case KVASER_USBCAN:
++              error_code = cmd->u.usbcan.error_event.error_code;
++              break;
++      }
++
++      switch (error_code) {
++      case KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL:
++              /* Received additional CAN message, when firmware TX queue is
++               * already full. Something is wrong with the driver.
++               * This should never happen!
++               */
++              dev_err(&dev->intf->dev,
++                      "Received error event TX_QUEUE_FULL\n");
++              break;
++      case KVASER_USB_LEAF_ERROR_EVENT_PARAM:
++              kvaser_usb_leaf_error_event_parameter(dev, cmd);
++              break;
++
++      default:
++              dev_warn(&dev->intf->dev,
++                       "Unhandled error event (%d)\n", error_code);
++              break;
++      }
++}
++
+ static void kvaser_usb_leaf_start_chip_reply(const struct kvaser_usb *dev,
+                                            const struct kvaser_cmd *cmd)
+ {
+@@ -1386,6 +1481,10 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
+               kvaser_usb_leaf_tx_acknowledge(dev, cmd);
+               break;
++      case CMD_ERROR_EVENT:
++              kvaser_usb_leaf_error_event(dev, cmd);
++              break;
++
+       /* Ignored commands */
+       case CMD_USBCAN_CLOCK_OVERFLOW_EVENT:
+               if (dev->driver_info->family != KVASER_USBCAN)
+-- 
+2.35.1
+
diff --git a/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-rename-leaf-usbcan-_c.patch b/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-rename-leaf-usbcan-_c.patch
new file mode 100644 (file)
index 0000000..e978a49
--- /dev/null
@@ -0,0 +1,136 @@
+From 5152cb83a7dcd7f333f9494d05de8ff680a1402e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 20:52:29 +0200
+Subject: can: kvaser_usb: kvaser_usb_leaf: Rename
+ {leaf,usbcan}_cmd_error_event to {leaf,usbcan}_cmd_can_error_event
+
+From: Jimmy Assarsson <extja@kvaser.com>
+
+[ Upstream commit 7ea56128dbf904a3359bcf9289cccdfa3c85c7e8 ]
+
+Prepare for handling CMD_ERROR_EVENT. Rename struct
+{leaf,usbcan}_cmd_error_event to {leaf,usbcan}_cmd_can_error_event.
+
+Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices")
+Reported-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Tested-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://lore.kernel.org/all/20221010185237.319219-4-extja@kvaser.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c  | 38 +++++++++----------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 26f32828f905..4f3d1150b2b2 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -233,7 +233,7 @@ struct kvaser_cmd_tx_acknowledge_header {
+       u8 tid;
+ } __packed;
+-struct leaf_cmd_error_event {
++struct leaf_cmd_can_error_event {
+       u8 tid;
+       u8 flags;
+       __le16 time[3];
+@@ -245,7 +245,7 @@ struct leaf_cmd_error_event {
+       u8 error_factor;
+ } __packed;
+-struct usbcan_cmd_error_event {
++struct usbcan_cmd_can_error_event {
+       u8 tid;
+       u8 padding;
+       u8 tx_errors_count_ch0;
+@@ -318,7 +318,7 @@ struct kvaser_cmd {
+                       struct leaf_cmd_softinfo softinfo;
+                       struct leaf_cmd_rx_can rx_can;
+                       struct leaf_cmd_chip_state_event chip_state_event;
+-                      struct leaf_cmd_error_event error_event;
++                      struct leaf_cmd_can_error_event can_error_event;
+                       struct leaf_cmd_log_message log_message;
+                       struct kvaser_cmd_cap_req cap_req;
+                       struct kvaser_cmd_cap_res cap_res;
+@@ -328,7 +328,7 @@ struct kvaser_cmd {
+                       struct usbcan_cmd_softinfo softinfo;
+                       struct usbcan_cmd_rx_can rx_can;
+                       struct usbcan_cmd_chip_state_event chip_state_event;
+-                      struct usbcan_cmd_error_event error_event;
++                      struct usbcan_cmd_can_error_event can_error_event;
+               } __packed usbcan;
+               struct kvaser_cmd_tx_can tx_can;
+@@ -350,7 +350,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = {
+       [CMD_RX_EXT_MESSAGE]            = kvaser_fsize(u.leaf.rx_can),
+       [CMD_LEAF_LOG_MESSAGE]          = kvaser_fsize(u.leaf.log_message),
+       [CMD_CHIP_STATE_EVENT]          = kvaser_fsize(u.leaf.chip_state_event),
+-      [CMD_CAN_ERROR_EVENT]           = kvaser_fsize(u.leaf.error_event),
++      [CMD_CAN_ERROR_EVENT]           = kvaser_fsize(u.leaf.can_error_event),
+       [CMD_GET_CAPABILITIES_RESP]     = kvaser_fsize(u.leaf.cap_res),
+       /* ignored events: */
+       [CMD_FLUSH_QUEUE_REPLY]         = CMD_SIZE_ANY,
+@@ -365,7 +365,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = {
+       [CMD_RX_STD_MESSAGE]            = kvaser_fsize(u.usbcan.rx_can),
+       [CMD_RX_EXT_MESSAGE]            = kvaser_fsize(u.usbcan.rx_can),
+       [CMD_CHIP_STATE_EVENT]          = kvaser_fsize(u.usbcan.chip_state_event),
+-      [CMD_CAN_ERROR_EVENT]           = kvaser_fsize(u.usbcan.error_event),
++      [CMD_CAN_ERROR_EVENT]           = kvaser_fsize(u.usbcan.can_error_event),
+       /* ignored events: */
+       [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY,
+ };
+@@ -1137,11 +1137,11 @@ static void kvaser_usb_leaf_usbcan_rx_error(const struct kvaser_usb *dev,
+       case CMD_CAN_ERROR_EVENT:
+               es.channel = 0;
+-              es.status = cmd->u.usbcan.error_event.status_ch0;
+-              es.txerr = cmd->u.usbcan.error_event.tx_errors_count_ch0;
+-              es.rxerr = cmd->u.usbcan.error_event.rx_errors_count_ch0;
++              es.status = cmd->u.usbcan.can_error_event.status_ch0;
++              es.txerr = cmd->u.usbcan.can_error_event.tx_errors_count_ch0;
++              es.rxerr = cmd->u.usbcan.can_error_event.rx_errors_count_ch0;
+               es.usbcan.other_ch_status =
+-                      cmd->u.usbcan.error_event.status_ch1;
++                      cmd->u.usbcan.can_error_event.status_ch1;
+               kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es);
+               /* The USBCAN firmware supports up to 2 channels.
+@@ -1149,13 +1149,13 @@ static void kvaser_usb_leaf_usbcan_rx_error(const struct kvaser_usb *dev,
+                */
+               if (dev->nchannels == MAX_USBCAN_NET_DEVICES) {
+                       es.channel = 1;
+-                      es.status = cmd->u.usbcan.error_event.status_ch1;
++                      es.status = cmd->u.usbcan.can_error_event.status_ch1;
+                       es.txerr =
+-                              cmd->u.usbcan.error_event.tx_errors_count_ch1;
++                              cmd->u.usbcan.can_error_event.tx_errors_count_ch1;
+                       es.rxerr =
+-                              cmd->u.usbcan.error_event.rx_errors_count_ch1;
++                              cmd->u.usbcan.can_error_event.rx_errors_count_ch1;
+                       es.usbcan.other_ch_status =
+-                              cmd->u.usbcan.error_event.status_ch0;
++                              cmd->u.usbcan.can_error_event.status_ch0;
+                       kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es);
+               }
+               break;
+@@ -1172,11 +1172,11 @@ static void kvaser_usb_leaf_leaf_rx_error(const struct kvaser_usb *dev,
+       switch (cmd->id) {
+       case CMD_CAN_ERROR_EVENT:
+-              es.channel = cmd->u.leaf.error_event.channel;
+-              es.status = cmd->u.leaf.error_event.status;
+-              es.txerr = cmd->u.leaf.error_event.tx_errors_count;
+-              es.rxerr = cmd->u.leaf.error_event.rx_errors_count;
+-              es.leaf.error_factor = cmd->u.leaf.error_event.error_factor;
++              es.channel = cmd->u.leaf.can_error_event.channel;
++              es.status = cmd->u.leaf.can_error_event.status;
++              es.txerr = cmd->u.leaf.can_error_event.tx_errors_count;
++              es.rxerr = cmd->u.leaf.can_error_event.rx_errors_count;
++              es.leaf.error_factor = cmd->u.leaf.can_error_event.error_factor;
+               break;
+       case CMD_LEAF_LOG_MESSAGE:
+               es.channel = cmd->u.leaf.log_message.channel;
+-- 
+2.35.1
+
diff --git a/queue-5.10/can-kvaser_usb_leaf-fix-bogus-restart-events.patch b/queue-5.10/can-kvaser_usb_leaf-fix-bogus-restart-events.patch
new file mode 100644 (file)
index 0000000..4162c0a
--- /dev/null
@@ -0,0 +1,66 @@
+From f19aef83f66da2fb90cc830ab70fb50f7422a260 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 20:52:35 +0200
+Subject: can: kvaser_usb_leaf: Fix bogus restart events
+
+From: Anssi Hannula <anssi.hannula@bitwise.fi>
+
+[ Upstream commit 90904d326269a38fe5dd895fb2db7c03199654c4 ]
+
+When auto-restart is enabled, the kvaser_usb_leaf driver considers
+transition from any state >= CAN_STATE_BUS_OFF as a bus-off recovery
+event (restart).
+
+However, these events may occur at interface startup time before
+kvaser_usb_open() has set the state to CAN_STATE_ERROR_ACTIVE, causing
+restarts counter to increase and CAN_ERR_RESTARTED to be sent despite no
+actual restart having occurred.
+
+Fix that by making the auto-restart condition checks more strict so that
+they only trigger when the interface was actually in the BUS_OFF state.
+
+Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices")
+Tested-by: Jimmy Assarsson <extja@kvaser.com>
+Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://lore.kernel.org/all/20221010185237.319219-10-extja@kvaser.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 52ac6446634d..d1877ff2ff71 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -899,7 +899,7 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev,
+       context = &priv->tx_contexts[tid % dev->max_tx_urbs];
+       /* Sometimes the state change doesn't come after a bus-off event */
+-      if (priv->can.restart_ms && priv->can.state >= CAN_STATE_BUS_OFF) {
++      if (priv->can.restart_ms && priv->can.state == CAN_STATE_BUS_OFF) {
+               struct sk_buff *skb;
+               struct can_frame *cf;
+@@ -1002,7 +1002,7 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
+       }
+       if (priv->can.restart_ms &&
+-          cur_state >= CAN_STATE_BUS_OFF &&
++          cur_state == CAN_STATE_BUS_OFF &&
+           new_state < CAN_STATE_BUS_OFF)
+               priv->can.can_stats.restarts++;
+@@ -1092,7 +1092,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+               }
+               if (priv->can.restart_ms &&
+-                  old_state >= CAN_STATE_BUS_OFF &&
++                  old_state == CAN_STATE_BUS_OFF &&
+                   new_state < CAN_STATE_BUS_OFF) {
+                       cf->can_id |= CAN_ERR_RESTARTED;
+                       netif_carrier_on(priv->netdev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/can-kvaser_usb_leaf-fix-improved-state-not-being-rep.patch b/queue-5.10/can-kvaser_usb_leaf-fix-improved-state-not-being-rep.patch
new file mode 100644 (file)
index 0000000..64647e3
--- /dev/null
@@ -0,0 +1,259 @@
+From aff799e703eb94fb4d96478eff3deee730ec8dd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 20:52:32 +0200
+Subject: can: kvaser_usb_leaf: Fix improved state not being reported
+
+From: Anssi Hannula <anssi.hannula@bitwise.fi>
+
+[ Upstream commit 8d21f5927ae604881f98587fabf6753f88730968 ]
+
+The tested 0bfd:0017 Kvaser Memorator Professional HS/HS FW 2.0.50 and
+0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778 do not seem to send
+any unsolicited events when error counters decrease or when the device
+transitions from ERROR_PASSIVE to ERROR_ACTIVE (or WARNING).
+
+This causes the interface to e.g. indefinitely stay in the ERROR_PASSIVE
+state.
+
+Fix that by asking for chip state (inc. counters) event every 0.5 secs
+when error counters are non-zero.
+
+Since there are non-error-counter devices, also always poll in
+ERROR_PASSIVE even if the counters show zero.
+
+Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices")
+Tested-by: Jimmy Assarsson <extja@kvaser.com>
+Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://lore.kernel.org/all/20221010185237.319219-7-extja@kvaser.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb.h   |  7 +++
+ .../net/can/usb/kvaser_usb/kvaser_usb_core.c  | 19 +++++-
+ .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c  | 58 +++++++++++++++++++
+ 3 files changed, 81 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+index 62958f04a2f2..1f4583f1dae2 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+@@ -104,6 +104,9 @@ struct kvaser_usb_net_priv {
+       struct can_priv can;
+       struct can_berr_counter bec;
++      /* subdriver-specific data */
++      void *sub_priv;
++
+       struct kvaser_usb *dev;
+       struct net_device *netdev;
+       int channel;
+@@ -125,6 +128,8 @@ struct kvaser_usb_net_priv {
+  *
+  * @dev_setup_endpoints:      setup USB in and out endpoints
+  * @dev_init_card:            initialize card
++ * @dev_init_channel:         initialize channel
++ * @dev_remove_channel:               uninitialize channel
+  * @dev_get_software_info:    get software info
+  * @dev_get_software_details: get software details
+  * @dev_get_card_info:                get card info
+@@ -146,6 +151,8 @@ struct kvaser_usb_dev_ops {
+                                   struct can_berr_counter *bec);
+       int (*dev_setup_endpoints)(struct kvaser_usb *dev);
+       int (*dev_init_card)(struct kvaser_usb *dev);
++      int (*dev_init_channel)(struct kvaser_usb_net_priv *priv);
++      void (*dev_remove_channel)(struct kvaser_usb_net_priv *priv);
+       int (*dev_get_software_info)(struct kvaser_usb *dev);
+       int (*dev_get_software_details)(struct kvaser_usb *dev);
+       int (*dev_get_card_info)(struct kvaser_usb *dev);
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+index 7491f85e85b3..2c816d8929da 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+@@ -645,6 +645,7 @@ static const struct net_device_ops kvaser_usb_netdev_ops = {
+ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
+ {
++      const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
+       int i;
+       for (i = 0; i < dev->nchannels; i++) {
+@@ -660,6 +661,9 @@ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
+               if (!dev->nets[i])
+                       continue;
++              if (ops->dev_remove_channel)
++                      ops->dev_remove_channel(dev->nets[i]);
++
+               free_candev(dev->nets[i]->netdev);
+       }
+ }
+@@ -727,17 +731,26 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+       dev->nets[channel] = priv;
++      if (ops->dev_init_channel) {
++              err = ops->dev_init_channel(priv);
++              if (err)
++                      goto err;
++      }
++
+       err = register_candev(netdev);
+       if (err) {
+               dev_err(&dev->intf->dev, "Failed to register CAN device\n");
+-              free_candev(netdev);
+-              dev->nets[channel] = NULL;
+-              return err;
++              goto err;
+       }
+       netdev_dbg(netdev, "device registered\n");
+       return 0;
++
++err:
++      free_candev(netdev);
++      dev->nets[channel] = NULL;
++      return err;
+ }
+ static int kvaser_usb_probe(struct usb_interface *intf,
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index b43631eaccf1..6d45ae6f2a08 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -20,6 +20,7 @@
+ #include <linux/string.h>
+ #include <linux/types.h>
+ #include <linux/usb.h>
++#include <linux/workqueue.h>
+ #include <linux/can.h>
+ #include <linux/can/dev.h>
+@@ -55,6 +56,7 @@
+ #define CMD_RX_EXT_MESSAGE            14
+ #define CMD_TX_EXT_MESSAGE            15
+ #define CMD_SET_BUS_PARAMS            16
++#define CMD_GET_CHIP_STATE            19
+ #define CMD_CHIP_STATE_EVENT          20
+ #define CMD_SET_CTRL_MODE             21
+ #define CMD_RESET_CHIP                        24
+@@ -420,6 +422,12 @@ struct kvaser_usb_err_summary {
+       };
+ };
++struct kvaser_usb_net_leaf_priv {
++      struct kvaser_usb_net_priv *net;
++
++      struct delayed_work chip_state_req_work;
++};
++
+ static const struct can_bittiming_const kvaser_usb_leaf_m16c_bittiming_const = {
+       .name = "kvaser_usb_ucii",
+       .tseg1_min = 4,
+@@ -947,6 +955,16 @@ static int kvaser_usb_leaf_simple_cmd_async(struct kvaser_usb_net_priv *priv,
+       return err;
+ }
++static void kvaser_usb_leaf_chip_state_req_work(struct work_struct *work)
++{
++      struct kvaser_usb_net_leaf_priv *leaf =
++              container_of(work, struct kvaser_usb_net_leaf_priv,
++                           chip_state_req_work.work);
++      struct kvaser_usb_net_priv *priv = leaf->net;
++
++      kvaser_usb_leaf_simple_cmd_async(priv, CMD_GET_CHIP_STATE);
++}
++
+ static void
+ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
+                                       const struct kvaser_usb_err_summary *es,
+@@ -1018,6 +1036,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+       struct sk_buff *skb;
+       struct net_device_stats *stats;
+       struct kvaser_usb_net_priv *priv;
++      struct kvaser_usb_net_leaf_priv *leaf;
+       enum can_state old_state, new_state;
+       if (es->channel >= dev->nchannels) {
+@@ -1027,6 +1046,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+       }
+       priv = dev->nets[es->channel];
++      leaf = priv->sub_priv;
+       stats = &priv->netdev->stats;
+       /* Update all of the CAN interface's state and error counters before
+@@ -1043,6 +1063,14 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+       kvaser_usb_leaf_rx_error_update_can_state(priv, es, &tmp_cf);
+       new_state = priv->can.state;
++      /* If there are errors, request status updates periodically as we do
++       * not get automatic notifications of improved state.
++       */
++      if (new_state < CAN_STATE_BUS_OFF &&
++          (es->rxerr || es->txerr || new_state == CAN_STATE_ERROR_PASSIVE))
++              schedule_delayed_work(&leaf->chip_state_req_work,
++                                    msecs_to_jiffies(500));
++
+       skb = alloc_can_err_skb(priv->netdev, &cf);
+       if (!skb) {
+               stats->rx_dropped++;
+@@ -1577,10 +1605,13 @@ static int kvaser_usb_leaf_start_chip(struct kvaser_usb_net_priv *priv)
+ static int kvaser_usb_leaf_stop_chip(struct kvaser_usb_net_priv *priv)
+ {
++      struct kvaser_usb_net_leaf_priv *leaf = priv->sub_priv;
+       int err;
+       reinit_completion(&priv->stop_comp);
++      cancel_delayed_work(&leaf->chip_state_req_work);
++
+       err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP,
+                                             priv->channel);
+       if (err)
+@@ -1627,6 +1658,31 @@ static int kvaser_usb_leaf_init_card(struct kvaser_usb *dev)
+       return 0;
+ }
++static int kvaser_usb_leaf_init_channel(struct kvaser_usb_net_priv *priv)
++{
++      struct kvaser_usb_net_leaf_priv *leaf;
++
++      leaf = devm_kzalloc(&priv->dev->intf->dev, sizeof(*leaf), GFP_KERNEL);
++      if (!leaf)
++              return -ENOMEM;
++
++      leaf->net = priv;
++      INIT_DELAYED_WORK(&leaf->chip_state_req_work,
++                        kvaser_usb_leaf_chip_state_req_work);
++
++      priv->sub_priv = leaf;
++
++      return 0;
++}
++
++static void kvaser_usb_leaf_remove_channel(struct kvaser_usb_net_priv *priv)
++{
++      struct kvaser_usb_net_leaf_priv *leaf = priv->sub_priv;
++
++      if (leaf)
++              cancel_delayed_work_sync(&leaf->chip_state_req_work);
++}
++
+ static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
+ {
+       struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+@@ -1724,6 +1780,8 @@ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = {
+       .dev_get_berr_counter = kvaser_usb_leaf_get_berr_counter,
+       .dev_setup_endpoints = kvaser_usb_leaf_setup_endpoints,
+       .dev_init_card = kvaser_usb_leaf_init_card,
++      .dev_init_channel = kvaser_usb_leaf_init_channel,
++      .dev_remove_channel = kvaser_usb_leaf_remove_channel,
+       .dev_get_software_info = kvaser_usb_leaf_get_software_info,
+       .dev_get_software_details = NULL,
+       .dev_get_card_info = kvaser_usb_leaf_get_card_info,
+-- 
+2.35.1
+
diff --git a/queue-5.10/can-kvaser_usb_leaf-fix-wrong-can-state-after-stoppi.patch b/queue-5.10/can-kvaser_usb_leaf-fix-wrong-can-state-after-stoppi.patch
new file mode 100644 (file)
index 0000000..61aad33
--- /dev/null
@@ -0,0 +1,45 @@
+From 8c530af8ac9c2023d7e31169a65e08fa02637e31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 20:52:33 +0200
+Subject: can: kvaser_usb_leaf: Fix wrong CAN state after stopping
+
+From: Anssi Hannula <anssi.hannula@bitwise.fi>
+
+[ Upstream commit a11249acf802341294557895d8e5f6aef080253f ]
+
+0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778 sends a
+CMD_CHIP_STATE_EVENT indicating bus-off after stopping the device,
+causing a stopped device to appear as CAN_STATE_BUS_OFF instead of
+CAN_STATE_STOPPED.
+
+Fix that by not handling error events on stopped devices.
+
+Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices")
+Tested-by: Jimmy Assarsson <extja@kvaser.com>
+Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://lore.kernel.org/all/20221010185237.319219-8-extja@kvaser.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 6d45ae6f2a08..52ac6446634d 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -1049,6 +1049,10 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+       leaf = priv->sub_priv;
+       stats = &priv->netdev->stats;
++      /* Ignore e.g. state change to bus-off reported just after stopping */
++      if (!netif_running(priv->netdev))
++              return;
++
+       /* Update all of the CAN interface's state and error counters before
+        * trying any memory allocation that can actually fail with -ENOMEM.
+        *
+-- 
+2.35.1
+
diff --git a/queue-5.10/can-kvaser_usb_leaf-set-warning-state-even-without-b.patch b/queue-5.10/can-kvaser_usb_leaf-set-warning-state-even-without-b.patch
new file mode 100644 (file)
index 0000000..ca92090
--- /dev/null
@@ -0,0 +1,76 @@
+From eebddaeb8ec40653ae8dd2f8e33715446c20c391 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 20:52:31 +0200
+Subject: can: kvaser_usb_leaf: Set Warning state even without bus errors
+
+From: Anssi Hannula <anssi.hannula@bitwise.fi>
+
+[ Upstream commit df1b7af2761b935f63b4a53e789d41ed859edf61 ]
+
+kvaser_usb_leaf_rx_error_update_can_state() sets error state according
+to error counters when the hardware does not indicate a specific state
+directly.
+
+However, this is currently gated behind a check for
+M16C_STATE_BUS_ERROR which does not always seem to be set when error
+counters are increasing, and may not be set when error counters are
+decreasing.
+
+This causes the CAN_STATE_ERROR_WARNING state to not be set in some
+cases even when appropriate.
+
+Change the code to set error state from counters even without
+M16C_STATE_BUS_ERROR.
+
+The Error-Passive case seems superfluous as it is already set via
+M16C_STATE_BUS_PASSIVE flag above, but it is kept for now.
+
+Tested with 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778.
+
+Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices")
+Tested-by: Jimmy Assarsson <extja@kvaser.com>
+Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi>
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://lore.kernel.org/all/20221010185237.319219-6-extja@kvaser.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c  | 20 ++++++++-----------
+ 1 file changed, 8 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 3c3e78992b55..b43631eaccf1 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -965,20 +965,16 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
+               new_state = CAN_STATE_BUS_OFF;
+       } else if (es->status & M16C_STATE_BUS_PASSIVE) {
+               new_state = CAN_STATE_ERROR_PASSIVE;
+-      } else if (es->status & M16C_STATE_BUS_ERROR) {
++      } else if ((es->status & M16C_STATE_BUS_ERROR) &&
++                 cur_state >= CAN_STATE_BUS_OFF) {
+               /* Guard against spurious error events after a busoff */
+-              if (cur_state < CAN_STATE_BUS_OFF) {
+-                      if (es->txerr >= 128 || es->rxerr >= 128)
+-                              new_state = CAN_STATE_ERROR_PASSIVE;
+-                      else if (es->txerr >= 96 || es->rxerr >= 96)
+-                              new_state = CAN_STATE_ERROR_WARNING;
+-                      else if (cur_state > CAN_STATE_ERROR_ACTIVE)
+-                              new_state = CAN_STATE_ERROR_ACTIVE;
+-              }
+-      }
+-
+-      if (!es->status)
++      } else if (es->txerr >= 128 || es->rxerr >= 128) {
++              new_state = CAN_STATE_ERROR_PASSIVE;
++      } else if (es->txerr >= 96 || es->rxerr >= 96) {
++              new_state = CAN_STATE_ERROR_WARNING;
++      } else {
+               new_state = CAN_STATE_ERROR_ACTIVE;
++      }
+       if (new_state != cur_state) {
+               tx_state = (es->txerr >= es->rxerr) ? new_state : 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/can-tcan4x5x-remove-invalid-write-in-clear_interrupt.patch b/queue-5.10/can-tcan4x5x-remove-invalid-write-in-clear_interrupt.patch
new file mode 100644 (file)
index 0000000..4728785
--- /dev/null
@@ -0,0 +1,44 @@
+From 064ab84cef3ac1403e79b1b92e9fe8a284073361 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 12:57:25 +0100
+Subject: can: tcan4x5x: Remove invalid write in clear_interrupts
+
+From: Markus Schneider-Pargmann <msp@baylibre.com>
+
+[ Upstream commit 40c9e4f676abbe194541d88e796341c92d5a13c0 ]
+
+Register 0x824 TCAN4X5X_MCAN_INT_REG is a read-only register. Any writes
+to this register do not have any effect.
+
+Remove this write. The m_can driver aldready clears the interrupts in
+m_can_isr() by writing to M_CAN_IR which is translated to register
+0x1050 which is a writable version of this register.
+
+Fixes: 5443c226ba91 ("can: tcan4x5x: Add tcan4x5x driver to the kernel")
+Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Link: https://lore.kernel.org/all/20221206115728.1056014-9-msp@baylibre.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/m_can/tcan4x5x.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/drivers/net/can/m_can/tcan4x5x.c b/drivers/net/can/m_can/tcan4x5x.c
+index f169d9090e52..f903f78af087 100644
+--- a/drivers/net/can/m_can/tcan4x5x.c
++++ b/drivers/net/can/m_can/tcan4x5x.c
+@@ -294,11 +294,6 @@ static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev)
+       if (ret)
+               return ret;
+-      ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_MCAN_INT_REG,
+-                                    TCAN4X5X_ENABLE_MCAN_INT);
+-      if (ret)
+-              return ret;
+-
+       ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_INT_FLAGS,
+                                     TCAN4X5X_CLEAR_ALL_INT);
+       if (ret)
+-- 
+2.35.1
+
diff --git a/queue-5.10/chardev-fix-error-handling-in-cdev_device_add.patch b/queue-5.10/chardev-fix-error-handling-in-cdev_device_add.patch
new file mode 100644 (file)
index 0000000..0725ba2
--- /dev/null
@@ -0,0 +1,54 @@
+From 6341c7f0a7408024c3443671f08628817c2843db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 11:02:37 +0800
+Subject: chardev: fix error handling in cdev_device_add()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 11fa7fefe3d8fac7da56bc9aa3dd5fb3081ca797 ]
+
+While doing fault injection test, I got the following report:
+
+------------[ cut here ]------------
+kobject: '(null)' (0000000039956980): is not initialized, yet kobject_put() is being called.
+WARNING: CPU: 3 PID: 6306 at kobject_put+0x23d/0x4e0
+CPU: 3 PID: 6306 Comm: 283 Tainted: G        W          6.1.0-rc2-00005-g307c1086d7c9 #1253
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
+RIP: 0010:kobject_put+0x23d/0x4e0
+Call Trace:
+ <TASK>
+ cdev_device_add+0x15e/0x1b0
+ __iio_device_register+0x13b4/0x1af0 [industrialio]
+ __devm_iio_device_register+0x22/0x90 [industrialio]
+ max517_probe+0x3d8/0x6b4 [max517]
+ i2c_device_probe+0xa81/0xc00
+
+When device_add() is injected fault and returns error, if dev->devt is not set,
+cdev_add() is not called, cdev_del() is not needed. Fix this by checking dev->devt
+in error path.
+
+Fixes: 233ed09d7fda ("chardev: add helper function to register char devs with a struct device")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221202030237.520280-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/char_dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/char_dev.c b/fs/char_dev.c
+index ba0ded7842a7..3f667292608c 100644
+--- a/fs/char_dev.c
++++ b/fs/char_dev.c
+@@ -547,7 +547,7 @@ int cdev_device_add(struct cdev *cdev, struct device *dev)
+       }
+       rc = device_add(dev);
+-      if (rc)
++      if (rc && dev->devt)
+               cdev_del(cdev);
+       return rc;
+-- 
+2.35.1
+
diff --git a/queue-5.10/class-fix-possible-memory-leak-in-__class_register.patch b/queue-5.10/class-fix-possible-memory-leak-in-__class_register.patch
new file mode 100644 (file)
index 0000000..4cc9c81
--- /dev/null
@@ -0,0 +1,71 @@
+From 7a8ee25a0fec17929e448bac7a5f2175b920c351 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Oct 2022 16:28:03 +0800
+Subject: class: fix possible memory leak in __class_register()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 8c3e8a6bdb5253b97ad532570f8b5db5f7a06407 ]
+
+If class_add_groups() returns error, the 'cp->subsys' need be
+unregister, and the 'cp' need be freed.
+
+We can not call kset_unregister() here, because the 'cls' will
+be freed in callback function class_release() and it's also
+freed in caller's error path, it will cause double free.
+
+So fix this by calling kobject_del() and kfree_const(name) to
+cleanup kobject. Besides, call kfree() to free the 'cp'.
+
+Fault injection test can trigger this:
+
+unreferenced object 0xffff888102fa8190 (size 8):
+  comm "modprobe", pid 502, jiffies 4294906074 (age 49.296s)
+  hex dump (first 8 bytes):
+    70 6b 74 63 64 76 64 00                          pktcdvd.
+  backtrace:
+    [<00000000e7c7703d>] __kmalloc_track_caller+0x1ae/0x320
+    [<000000005e4d70bc>] kstrdup+0x3a/0x70
+    [<00000000c2e5e85a>] kstrdup_const+0x68/0x80
+    [<000000000049a8c7>] kvasprintf_const+0x10b/0x190
+    [<0000000029123163>] kobject_set_name_vargs+0x56/0x150
+    [<00000000747219c9>] kobject_set_name+0xab/0xe0
+    [<0000000005f1ea4e>] __class_register+0x15c/0x49a
+
+unreferenced object 0xffff888037274000 (size 1024):
+  comm "modprobe", pid 502, jiffies 4294906074 (age 49.296s)
+  hex dump (first 32 bytes):
+    00 40 27 37 80 88 ff ff 00 40 27 37 80 88 ff ff  .@'7.....@'7....
+    00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00  .....N..........
+  backtrace:
+    [<00000000151f9600>] kmem_cache_alloc_trace+0x17c/0x2f0
+    [<00000000ecf3dd95>] __class_register+0x86/0x49a
+
+Fixes: ced6473e7486 ("driver core: class: add class_groups support")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221026082803.3458760-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/class.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/base/class.c b/drivers/base/class.c
+index c3451481194e..ef7ff822bc08 100644
+--- a/drivers/base/class.c
++++ b/drivers/base/class.c
+@@ -192,6 +192,11 @@ int __class_register(struct class *cls, struct lock_class_key *key)
+       }
+       error = class_add_groups(class_get(cls), cls->class_groups);
+       class_put(cls);
++      if (error) {
++              kobject_del(&cp->subsys.kobj);
++              kfree_const(cp->subsys.kobj.name);
++              kfree(cp);
++      }
+       return error;
+ }
+ EXPORT_SYMBOL_GPL(__class_register);
+-- 
+2.35.1
+
diff --git a/queue-5.10/clk-imx-replace-osc_hdmi-with-dummy.patch b/queue-5.10/clk-imx-replace-osc_hdmi-with-dummy.patch
new file mode 100644 (file)
index 0000000..a15dd89
--- /dev/null
@@ -0,0 +1,70 @@
+From 1e6769d1b60aca2c9acca1177c9e474895bcff61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 12:36:34 +0100
+Subject: clk: imx: replace osc_hdmi with dummy
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit e7fa365ff66f16772dc06b480cd78f858d10856b ]
+
+There is no occurrence of the hdmi oscillator in the reference manual
+(document IMX8MNRM Rev 2, 07/2022). Further, if we consider the indexes
+76-81 and 134 of the "Clock Root" table of chapter 5 of the RM, there is
+no entry for the source select bits 101b, which is the setting referenced
+by "osc_hdmi".
+Fix by renaming "osc_hdmi" with "dummy", a clock which has already been
+used for missing source select bits.
+
+Tested on the BSH SystemMaster (SMM) S2 board.
+
+Fixes: 96d6392b54dbb ("clk: imx: Add support for i.MX8MN clock driver")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Acked-by: Marco Felsch <m.felsch@pengutronix.de>
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20221117113637.1978703-3-dario.binacchi@amarulasolutions.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8mn.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
+index db122d94db58..8a49e072d6e8 100644
+--- a/drivers/clk/imx/clk-imx8mn.c
++++ b/drivers/clk/imx/clk-imx8mn.c
+@@ -105,27 +105,27 @@ static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll1_out
+                                                     "sys_pll3_out", "clk_ext4", };
+ static const char * const imx8mn_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-                                              "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++                                              "video_pll1_out", "sys_pll1_133m", "dummy",
+                                               "clk_ext3", "clk_ext4", };
+ static const char * const imx8mn_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-                                              "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++                                              "video_pll1_out", "sys_pll1_133m", "dummy",
+                                               "clk_ext3", "clk_ext4", };
+ static const char * const imx8mn_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-                                              "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++                                              "video_pll1_out", "sys_pll1_133m", "dummy",
+                                               "clk_ext2", "clk_ext3", };
+ static const char * const imx8mn_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-                                              "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++                                              "video_pll1_out", "sys_pll1_133m", "dummy",
+                                               "clk_ext3", "clk_ext4", };
+ static const char * const imx8mn_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-                                              "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++                                              "video_pll1_out", "sys_pll1_133m", "dummy",
+                                               "clk_ext3", "clk_ext4", };
+ static const char * const imx8mn_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-                                                "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++                                                "video_pll1_out", "sys_pll1_133m", "dummy",
+                                                 "clk_ext2", "clk_ext3", };
+ static const char * const imx8mn_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
+-- 
+2.35.1
+
diff --git a/queue-5.10/clk-qcom-clk-krait-fix-wrong-div2-functions.patch b/queue-5.10/clk-qcom-clk-krait-fix-wrong-div2-functions.patch
new file mode 100644 (file)
index 0000000..b2741ac
--- /dev/null
@@ -0,0 +1,40 @@
+From 74e6c571df0cae76c7e8d3c124db72027e7f29a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 22:56:25 +0100
+Subject: clk: qcom: clk-krait: fix wrong div2 functions
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+[ Upstream commit d676d3a3717cf726d3affedbe5ba98fc4ccad7b3 ]
+
+Currently div2 value is applied to the wrong bits. This is caused by a
+bug in the code where the shift is done only for lpl, for anything
+else the mask is not shifted to the correct bits.
+
+Fix this by correctly shift if lpl is not supported.
+
+Fixes: 4d7dc77babfe ("clk: qcom: Add support for Krait clocks")
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221108215625.30186-1-ansuelsmth@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-krait.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c
+index 90046428693c..e74fc81a14d0 100644
+--- a/drivers/clk/qcom/clk-krait.c
++++ b/drivers/clk/qcom/clk-krait.c
+@@ -98,6 +98,8 @@ static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate,
+       if (d->lpl)
+               mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift;
++      else
++              mask <<= d->shift;
+       spin_lock_irqsave(&krait_clock_reg_lock, flags);
+       val = krait_get_l2_indirect_reg(d->offset);
+-- 
+2.35.1
+
diff --git a/queue-5.10/clk-qcom-gcc-sm8250-use-retention-mode-for-usb-gdscs.patch b/queue-5.10/clk-qcom-gcc-sm8250-use-retention-mode-for-usb-gdscs.patch
new file mode 100644 (file)
index 0000000..d8ebd24
--- /dev/null
@@ -0,0 +1,48 @@
+From bf630b8f25a97317224d6674698bdd2a0a382c17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 14:43:20 +0530
+Subject: clk: qcom: gcc-sm8250: Use retention mode for USB GDSCs
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit ac1c5a03d3772b1db25e8092f771aa33f6ae2f7e ]
+
+USB controllers on SM8250 doesn't work after coming back from suspend.
+This can be fixed by keeping the USB GDSCs in retention mode so that
+hardware can keep them ON and put into rentention mode once the parent
+domain goes to a low power state.
+
+Fixes: 3e5770921a88 ("clk: qcom: gcc: Add global clock controller driver for SM8250")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221102091320.66007-1-manivannan.sadhasivam@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sm8250.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-sm8250.c b/drivers/clk/qcom/gcc-sm8250.c
+index ab594a0f0c40..7ec11acc8298 100644
+--- a/drivers/clk/qcom/gcc-sm8250.c
++++ b/drivers/clk/qcom/gcc-sm8250.c
+@@ -3268,7 +3268,7 @@ static struct gdsc usb30_prim_gdsc = {
+       .pd = {
+               .name = "usb30_prim_gdsc",
+       },
+-      .pwrsts = PWRSTS_OFF_ON,
++      .pwrsts = PWRSTS_RET_ON,
+ };
+ static struct gdsc usb30_sec_gdsc = {
+@@ -3276,7 +3276,7 @@ static struct gdsc usb30_sec_gdsc = {
+       .pd = {
+               .name = "usb30_sec_gdsc",
+       },
+-      .pwrsts = PWRSTS_OFF_ON,
++      .pwrsts = PWRSTS_RET_ON,
+ };
+ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
+-- 
+2.35.1
+
diff --git a/queue-5.10/clk-renesas-r9a06g032-repair-grave-increment-error.patch b/queue-5.10/clk-renesas-r9a06g032-repair-grave-increment-error.patch
new file mode 100644 (file)
index 0000000..3b93277
--- /dev/null
@@ -0,0 +1,47 @@
+From ca709f7ba2e818cee11128a0e55a3d58fba9d700 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Oct 2022 13:38:34 +0200
+Subject: clk: renesas: r9a06g032: Repair grave increment error
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 02693e11611e082e3c4d8653e8af028e43d31164 ]
+
+If condition (clkspec.np != pd->dev.of_node) is true, then the driver
+ends up in an endless loop, forever, locking up the machine.
+
+Fixes: aad03a66f902 ("clk: renesas: r9a06g032: Add clock domain support")
+Reviewed-by: Ralph Siemsen <ralph.siemsen@linaro.org>
+Signed-off-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Gareth Williams <gareth.williams.jx@renesas.com>
+Link: https://lore.kernel.org/r/20221028113834.7496-1-marex@denx.de
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/r9a06g032-clocks.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
+index 245150a5484a..285f6ac25372 100644
+--- a/drivers/clk/renesas/r9a06g032-clocks.c
++++ b/drivers/clk/renesas/r9a06g032-clocks.c
+@@ -386,7 +386,7 @@ static int r9a06g032_attach_dev(struct generic_pm_domain *pd,
+       int error;
+       int index;
+-      while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
++      while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i++,
+                                          &clkspec)) {
+               if (clkspec.np != pd->dev.of_node)
+                       continue;
+@@ -399,7 +399,6 @@ static int r9a06g032_attach_dev(struct generic_pm_domain *pd,
+                       if (error)
+                               return error;
+               }
+-              i++;
+       }
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/clk-rockchip-fix-memory-leak-in-rockchip_clk_registe.patch b/queue-5.10/clk-rockchip-fix-memory-leak-in-rockchip_clk_registe.patch
new file mode 100644 (file)
index 0000000..e9a22d6
--- /dev/null
@@ -0,0 +1,37 @@
+From 03b88322d3deea6b16747a4c11f51880940ab3b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 17:12:01 +0800
+Subject: clk: rockchip: Fix memory leak in rockchip_clk_register_pll()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 739a6a6bbdb793bd57938cb24aa5a6df89983546 ]
+
+If clk_register() fails, @pll->rate_table may have allocated memory by
+kmemdup(), so it needs to be freed, otherwise will cause memory leak
+issue, this patch fixes it.
+
+Fixes: 90c590254051 ("clk: rockchip: add clock type for pll clocks and pll used on rk3066")
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Link: https://lore.kernel.org/r/20221123091201.199819-1-xiujianfeng@huawei.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/rockchip/clk-pll.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
+index bbbf9ce42867..d0bd513ff3c3 100644
+--- a/drivers/clk/rockchip/clk-pll.c
++++ b/drivers/clk/rockchip/clk-pll.c
+@@ -981,6 +981,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
+       return mux_clk;
+ err_pll:
++      kfree(pll->rate_table);
+       clk_unregister(mux_clk);
+       mux_clk = pll_clk;
+ err_mux:
+-- 
+2.35.1
+
diff --git a/queue-5.10/clk-samsung-fix-memory-leak-in-_samsung_clk_register.patch b/queue-5.10/clk-samsung-fix-memory-leak-in-_samsung_clk_register.patch
new file mode 100644 (file)
index 0000000..445362e
--- /dev/null
@@ -0,0 +1,38 @@
+From 9184a1389066749832efbe8630e449c66c81629d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 11:20:15 +0800
+Subject: clk: samsung: Fix memory leak in _samsung_clk_register_pll()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 5174e5b0d1b669a489524192b6adcbb3c54ebc72 ]
+
+If clk_register() fails, @pll->rate_table may have allocated memory by
+kmemdup(), so it needs to be freed, otherwise will cause memory leak
+issue, this patch fixes it.
+
+Fixes: 3ff6e0d8d64d ("clk: samsung: Add support to register rate_table for samsung plls")
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Link: https://lore.kernel.org/r/20221123032015.63980-1-xiujianfeng@huawei.com
+Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/samsung/clk-pll.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
+index ac70ad785d8e..33df20f813d5 100644
+--- a/drivers/clk/samsung/clk-pll.c
++++ b/drivers/clk/samsung/clk-pll.c
+@@ -1390,6 +1390,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
+       if (ret) {
+               pr_err("%s: failed to register pll clock %s : %d\n",
+                       __func__, pll_clk->name, ret);
++              kfree(pll->rate_table);
+               kfree(pll);
+               return;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/clk-socfpga-clk-pll-remove-unused-variable-rc.patch b/queue-5.10/clk-socfpga-clk-pll-remove-unused-variable-rc.patch
new file mode 100644 (file)
index 0000000..6e9d579
--- /dev/null
@@ -0,0 +1,55 @@
+From e5c23b5f74e74d1aef89a05209e82e08477e2a1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Jan 2021 09:30:27 +0000
+Subject: clk: socfpga: clk-pll: Remove unused variable 'rc'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lee Jones <lee.jones@linaro.org>
+
+[ Upstream commit 75fddccbca32349570b2d53955982b4117fa5515 ]
+
+Fixes the following W=1 kernel build warning(s):
+
+ drivers/clk/socfpga/clk-pll.c: In function ‘__socfpga_pll_init’:
+ drivers/clk/socfpga/clk-pll.c:83:6: warning: variable ‘rc’ set but not used [-Wunused-but-set-variable]
+
+Cc: Dinh Nguyen <dinguyen@kernel.org>
+Cc: Michael Turquette <mturquette@baylibre.com>
+Cc: Stephen Boyd <sboyd@kernel.org>
+Cc: linux-clk@vger.kernel.org
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Link: https://lore.kernel.org/r/20210120093040.1719407-8-lee.jones@linaro.org
+Acked-by: Dinh Nguyen <dinguyen@kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: 0b8ba891ad4d ("clk: socfpga: Fix memory leak in socfpga_gate_init()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/socfpga/clk-pll.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c
+index e5fb786843f3..3cf99df7d005 100644
+--- a/drivers/clk/socfpga/clk-pll.c
++++ b/drivers/clk/socfpga/clk-pll.c
+@@ -80,7 +80,6 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node,
+       const char *parent_name[SOCFPGA_MAX_PARENTS];
+       struct clk_init_data init;
+       struct device_node *clkmgr_np;
+-      int rc;
+       of_property_read_u32(node, "reg", &reg);
+@@ -111,7 +110,7 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node,
+               kfree(pll_clk);
+               return NULL;
+       }
+-      rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
++      of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       return clk;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/clk-socfpga-fix-memory-leak-in-socfpga_gate_init.patch b/queue-5.10/clk-socfpga-fix-memory-leak-in-socfpga_gate_init.patch
new file mode 100644 (file)
index 0000000..6356e68
--- /dev/null
@@ -0,0 +1,48 @@
+From 6acff0ece45d78ae29878563fe308d219aa6f2ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 11:16:22 +0800
+Subject: clk: socfpga: Fix memory leak in socfpga_gate_init()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 0b8ba891ad4d1ef6bfa4c72efc83f9f9f855f68b ]
+
+Free @socfpga_clk and @ops on the error path to avoid memory leak issue.
+
+Fixes: a30a67be7b6e ("clk: socfpga: Don't have get_parent for single parent ops")
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Link: https://lore.kernel.org/r/20221123031622.63171-1-xiujianfeng@huawei.com
+Acked-by: Dinh Nguyen <dinguyen@kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/socfpga/clk-gate.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
+index 1ec9678d8cd3..ee2a2d284113 100644
+--- a/drivers/clk/socfpga/clk-gate.c
++++ b/drivers/clk/socfpga/clk-gate.c
+@@ -188,8 +188,10 @@ void __init socfpga_gate_init(struct device_node *node)
+               return;
+       ops = kmemdup(&gateclk_ops, sizeof(gateclk_ops), GFP_KERNEL);
+-      if (WARN_ON(!ops))
++      if (WARN_ON(!ops)) {
++              kfree(socfpga_clk);
+               return;
++      }
+       rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
+       if (rc)
+@@ -243,6 +245,7 @@ void __init socfpga_gate_init(struct device_node *node)
+       err = clk_hw_register(NULL, hw_clk);
+       if (err) {
++              kfree(ops);
+               kfree(socfpga_clk);
+               return;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/clk-socfpga-use-clk_hw_register-for-a5-c5.patch b/queue-5.10/clk-socfpga-use-clk_hw_register-for-a5-c5.patch
new file mode 100644 (file)
index 0000000..48b0ac6
--- /dev/null
@@ -0,0 +1,141 @@
+From e5bced431ff4fd0a2bb010014aa54cb0efeaa029 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Mar 2021 15:41:49 -0600
+Subject: clk: socfpga: use clk_hw_register for a5/c5
+
+From: Dinh Nguyen <dinguyen@kernel.org>
+
+[ Upstream commit 2c2b9c6067170de2a63e7e3d9f5bb205b870de7c ]
+
+As recommended by Stephen Boyd, convert the cyclone5/arria5 clock driver
+to use the clk_hw registration method.
+
+Suggested-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+Link: https://lore.kernel.org/r/20210302214151.1333447-1-dinguyen@kernel.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: 0b8ba891ad4d ("clk: socfpga: Fix memory leak in socfpga_gate_init()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/socfpga/clk-gate.c   | 11 +++++++----
+ drivers/clk/socfpga/clk-periph.c |  8 ++++----
+ drivers/clk/socfpga/clk-pll.c    | 18 +++++++++++-------
+ 3 files changed, 22 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
+index cf94a12459ea..1ec9678d8cd3 100644
+--- a/drivers/clk/socfpga/clk-gate.c
++++ b/drivers/clk/socfpga/clk-gate.c
+@@ -174,13 +174,14 @@ void __init socfpga_gate_init(struct device_node *node)
+       u32 div_reg[3];
+       u32 clk_phase[2];
+       u32 fixed_div;
+-      struct clk *clk;
++      struct clk_hw *hw_clk;
+       struct socfpga_gate_clk *socfpga_clk;
+       const char *clk_name = node->name;
+       const char *parent_name[SOCFPGA_MAX_PARENTS];
+       struct clk_init_data init;
+       struct clk_ops *ops;
+       int rc;
++      int err;
+       socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
+       if (WARN_ON(!socfpga_clk))
+@@ -238,12 +239,14 @@ void __init socfpga_gate_init(struct device_node *node)
+       init.parent_names = parent_name;
+       socfpga_clk->hw.hw.init = &init;
+-      clk = clk_register(NULL, &socfpga_clk->hw.hw);
+-      if (WARN_ON(IS_ERR(clk))) {
++      hw_clk = &socfpga_clk->hw.hw;
++
++      err = clk_hw_register(NULL, hw_clk);
++      if (err) {
+               kfree(socfpga_clk);
+               return;
+       }
+-      rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
++      rc = of_clk_add_provider(node, of_clk_src_simple_get, hw_clk);
+       if (WARN_ON(rc))
+               return;
+ }
+diff --git a/drivers/clk/socfpga/clk-periph.c b/drivers/clk/socfpga/clk-periph.c
+index 5e0c4b45f77f..43707e2d7248 100644
+--- a/drivers/clk/socfpga/clk-periph.c
++++ b/drivers/clk/socfpga/clk-periph.c
+@@ -51,7 +51,7 @@ static __init void __socfpga_periph_init(struct device_node *node,
+       const struct clk_ops *ops)
+ {
+       u32 reg;
+-      struct clk *clk;
++      struct clk_hw *hw_clk;
+       struct socfpga_periph_clk *periph_clk;
+       const char *clk_name = node->name;
+       const char *parent_name[SOCFPGA_MAX_PARENTS];
+@@ -94,13 +94,13 @@ static __init void __socfpga_periph_init(struct device_node *node,
+       init.parent_names = parent_name;
+       periph_clk->hw.hw.init = &init;
++      hw_clk = &periph_clk->hw.hw;
+-      clk = clk_register(NULL, &periph_clk->hw.hw);
+-      if (WARN_ON(IS_ERR(clk))) {
++      if (clk_hw_register(NULL, hw_clk)) {
+               kfree(periph_clk);
+               return;
+       }
+-      rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
++      rc = of_clk_add_provider(node, of_clk_src_simple_get, hw_clk);
+ }
+ void __init socfpga_periph_init(struct device_node *node)
+diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c
+index 3cf99df7d005..dcb573d44034 100644
+--- a/drivers/clk/socfpga/clk-pll.c
++++ b/drivers/clk/socfpga/clk-pll.c
+@@ -70,16 +70,18 @@ static const struct clk_ops clk_pll_ops = {
+       .get_parent = clk_pll_get_parent,
+ };
+-static __init struct clk *__socfpga_pll_init(struct device_node *node,
++static __init struct clk_hw *__socfpga_pll_init(struct device_node *node,
+       const struct clk_ops *ops)
+ {
+       u32 reg;
+-      struct clk *clk;
++      struct clk_hw *hw_clk;
+       struct socfpga_pll *pll_clk;
+       const char *clk_name = node->name;
+       const char *parent_name[SOCFPGA_MAX_PARENTS];
+       struct clk_init_data init;
+       struct device_node *clkmgr_np;
++      int rc;
++      int err;
+       of_property_read_u32(node, "reg", &reg);
+@@ -105,13 +107,15 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node,
+       pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
+-      clk = clk_register(NULL, &pll_clk->hw.hw);
+-      if (WARN_ON(IS_ERR(clk))) {
++      hw_clk = &pll_clk->hw.hw;
++
++      err = clk_hw_register(NULL, hw_clk);
++      if (err) {
+               kfree(pll_clk);
+-              return NULL;
++              return ERR_PTR(err);
+       }
+-      of_clk_add_provider(node, of_clk_src_simple_get, clk);
+-      return clk;
++      rc = of_clk_add_provider(node, of_clk_src_simple_get, hw_clk);
++      return hw_clk;
+ }
+ void __init socfpga_pll_init(struct device_node *node)
+-- 
+2.35.1
+
diff --git a/queue-5.10/clk-st-fix-memory-leak-in-st_of_quadfs_setup.patch b/queue-5.10/clk-st-fix-memory-leak-in-st_of_quadfs_setup.patch
new file mode 100644 (file)
index 0000000..c4dfd53
--- /dev/null
@@ -0,0 +1,41 @@
+From ba5e809b4b0e978330ab42903c0182ed1d64681d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 21:36:14 +0800
+Subject: clk: st: Fix memory leak in st_of_quadfs_setup()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit cfd3ffb36f0d566846163118651d868e607300ba ]
+
+If st_clk_register_quadfs_pll() fails, @lock should be freed before goto
+@err_exit, otherwise will cause meory leak issue, fix it.
+
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Link: https://lore.kernel.org/r/20221122133614.184910-1-xiujianfeng@huawei.com
+Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/st/clkgen-fsyn.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
+index f1adc858b590..0e58a7cda427 100644
+--- a/drivers/clk/st/clkgen-fsyn.c
++++ b/drivers/clk/st/clkgen-fsyn.c
+@@ -942,9 +942,10 @@ static void __init st_of_quadfs_setup(struct device_node *np,
+       clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name, data,
+                       reg, lock);
+-      if (IS_ERR(clk))
++      if (IS_ERR(clk)) {
++              kfree(lock);
+               goto err_exit;
+-      else
++      } else
+               pr_debug("%s: parent %s rate %u\n",
+                       __clk_get_name(clk),
+                       __clk_get_name(clk_get_parent(clk)),
+-- 
+2.35.1
+
diff --git a/queue-5.10/clocksource-drivers-sh_cmt-access-registers-accordin.patch b/queue-5.10/clocksource-drivers-sh_cmt-access-registers-accordin.patch
new file mode 100644 (file)
index 0000000..1295db3
--- /dev/null
@@ -0,0 +1,195 @@
+From 573c1bf6688ec83d53b61ad5c56950898e4a4a9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Nov 2022 22:06:09 +0100
+Subject: clocksource/drivers/sh_cmt: Access registers according to spec
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 3f44f7156f59cae06e9160eafb5d8b2dfd09e639 ]
+
+Documentation for most CMTs say that it takes two input clocks before
+changes propagate to the timer. This is especially relevant when the timer
+is stopped to change further settings.
+
+Implement the delays according to the spec. To avoid unnecessary delays in
+atomic mode, also check if the to-be-written value actually differs.
+
+CMCNT is a bit special because testing showed that it requires 3 cycles to
+propagate, which affects all CMTs. Also, the WRFLAG needs to be checked
+before writing. This fixes "cannot clear CMCNT" messages which occur often
+on R-Car Gen4 SoCs, but only very rarely on older SoCs for some reason.
+
+Fixes: 81b3b2711072 ("clocksource: sh_cmt: Add support for multiple channels per device")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20221130210609.7718-1-wsa+renesas@sang-engineering.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clocksource/sh_cmt.c | 88 ++++++++++++++++++++++--------------
+ 1 file changed, 55 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
+index 65a1e2416402..66e4872ab34f 100644
+--- a/drivers/clocksource/sh_cmt.c
++++ b/drivers/clocksource/sh_cmt.c
+@@ -13,6 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/ioport.h>
+ #include <linux/irq.h>
+ #include <linux/module.h>
+@@ -116,6 +117,7 @@ struct sh_cmt_device {
+       void __iomem *mapbase;
+       struct clk *clk;
+       unsigned long rate;
++      unsigned int reg_delay;
+       raw_spinlock_t lock; /* Protect the shared start/stop register */
+@@ -247,10 +249,17 @@ static inline u32 sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
+ static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch, u32 value)
+ {
+-      if (ch->iostart)
+-              ch->cmt->info->write_control(ch->iostart, 0, value);
+-      else
+-              ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
++      u32 old_value = sh_cmt_read_cmstr(ch);
++
++      if (value != old_value) {
++              if (ch->iostart) {
++                      ch->cmt->info->write_control(ch->iostart, 0, value);
++                      udelay(ch->cmt->reg_delay);
++              } else {
++                      ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
++                      udelay(ch->cmt->reg_delay);
++              }
++      }
+ }
+ static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
+@@ -260,7 +269,12 @@ static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
+ static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch, u32 value)
+ {
+-      ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
++      u32 old_value = sh_cmt_read_cmcsr(ch);
++
++      if (value != old_value) {
++              ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
++              udelay(ch->cmt->reg_delay);
++      }
+ }
+ static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
+@@ -268,14 +282,33 @@ static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
+       return ch->cmt->info->read_count(ch->ioctrl, CMCNT);
+ }
+-static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value)
++static inline int sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value)
+ {
++      /* Tests showed that we need to wait 3 clocks here */
++      unsigned int cmcnt_delay = DIV_ROUND_UP(3 * ch->cmt->reg_delay, 2);
++      u32 reg;
++
++      if (ch->cmt->info->model > SH_CMT_16BIT) {
++              int ret = read_poll_timeout_atomic(sh_cmt_read_cmcsr, reg,
++                                                 !(reg & SH_CMT32_CMCSR_WRFLG),
++                                                 1, cmcnt_delay, false, ch);
++              if (ret < 0)
++                      return ret;
++      }
++
+       ch->cmt->info->write_count(ch->ioctrl, CMCNT, value);
++      udelay(cmcnt_delay);
++      return 0;
+ }
+ static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch, u32 value)
+ {
+-      ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
++      u32 old_value = ch->cmt->info->read_count(ch->ioctrl, CMCOR);
++
++      if (value != old_value) {
++              ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
++              udelay(ch->cmt->reg_delay);
++      }
+ }
+ static u32 sh_cmt_get_counter(struct sh_cmt_channel *ch, u32 *has_wrapped)
+@@ -319,7 +352,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
+ static int sh_cmt_enable(struct sh_cmt_channel *ch)
+ {
+-      int k, ret;
++      int ret;
+       pm_runtime_get_sync(&ch->cmt->pdev->dev);
+       dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
+@@ -347,26 +380,9 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch)
+       }
+       sh_cmt_write_cmcor(ch, 0xffffffff);
+-      sh_cmt_write_cmcnt(ch, 0);
+-
+-      /*
+-       * According to the sh73a0 user's manual, as CMCNT can be operated
+-       * only by the RCLK (Pseudo 32 kHz), there's one restriction on
+-       * modifying CMCNT register; two RCLK cycles are necessary before
+-       * this register is either read or any modification of the value
+-       * it holds is reflected in the LSI's actual operation.
+-       *
+-       * While at it, we're supposed to clear out the CMCNT as of this
+-       * moment, so make sure it's processed properly here.  This will
+-       * take RCLKx2 at maximum.
+-       */
+-      for (k = 0; k < 100; k++) {
+-              if (!sh_cmt_read_cmcnt(ch))
+-                      break;
+-              udelay(1);
+-      }
++      ret = sh_cmt_write_cmcnt(ch, 0);
+-      if (sh_cmt_read_cmcnt(ch)) {
++      if (ret || sh_cmt_read_cmcnt(ch)) {
+               dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n",
+                       ch->index);
+               ret = -ETIMEDOUT;
+@@ -976,8 +992,8 @@ MODULE_DEVICE_TABLE(of, sh_cmt_of_table);
+ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+ {
+-      unsigned int mask;
+-      unsigned int i;
++      unsigned int mask, i;
++      unsigned long rate;
+       int ret;
+       cmt->pdev = pdev;
+@@ -1013,10 +1029,16 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+       if (ret < 0)
+               goto err_clk_unprepare;
+-      if (cmt->info->width == 16)
+-              cmt->rate = clk_get_rate(cmt->clk) / 512;
+-      else
+-              cmt->rate = clk_get_rate(cmt->clk) / 8;
++      rate = clk_get_rate(cmt->clk);
++      if (!rate) {
++              ret = -EINVAL;
++              goto err_clk_disable;
++      }
++
++      /* We shall wait 2 input clks after register writes */
++      if (cmt->info->model >= SH_CMT_48BIT)
++              cmt->reg_delay = DIV_ROUND_UP(2UL * USEC_PER_SEC, rate);
++      cmt->rate = rate / (cmt->info->width == 16 ? 512 : 8);
+       /* Map the memory resource(s). */
+       ret = sh_cmt_map_memory(cmt);
+-- 
+2.35.1
+
diff --git a/queue-5.10/clocksource-drivers-sh_cmt-make-sure-channel-clock-s.patch b/queue-5.10/clocksource-drivers-sh_cmt-make-sure-channel-clock-s.patch
new file mode 100644 (file)
index 0000000..63a907b
--- /dev/null
@@ -0,0 +1,108 @@
+From 239b0c7c35cb532d308641d2da613a10086e9fb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Dec 2020 20:46:48 +0100
+Subject: clocksource/drivers/sh_cmt: Make sure channel clock supply is enabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 2a97d55333e4299f32c98cca6dc5c4db1c5855fc ]
+
+The Renesas Compare Match Timer 0 and 1 (CMT0/1) variants have a
+register to control the clock supply to the individual channels.
+Currently the driver does not touch this register, and relies on the
+documented initial value, which has the clock supply enabled for all
+channels present.
+
+However, when Linux starts on the APE6-EVM development board, only the
+clock supply to the first CMT1 channel is enabled.  Hence the first
+channel (used as a clockevent) works, while the second channel (used as
+a clocksource) does not.  Note that the default system clocksource is
+the Cortex-A15 architectured timer, and the user needs to manually
+switch to the CMT1 clocksource to trigger the broken behavior.
+
+Fix this by removing the fragile dependency on implicit reset and/or
+boot loader state, and by enabling the clock supply explicitly for all
+channels used instead.  This requires postponing the clk_disable() call,
+else the timer's registers cannot be accessed in sh_cmt_setup_channel().
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20201210194648.2901899-1-geert+renesas@glider.be
+Stable-dep-of: 3f44f7156f59 ("clocksource/drivers/sh_cmt: Access registers according to spec")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clocksource/sh_cmt.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
+index 2acfcc966bb5..65a1e2416402 100644
+--- a/drivers/clocksource/sh_cmt.c
++++ b/drivers/clocksource/sh_cmt.c
+@@ -235,6 +235,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
+ #define CMCNT 1 /* channel register */
+ #define CMCOR 2 /* channel register */
++#define CMCLKE        0x1000  /* CLK Enable Register (R-Car Gen2) */
++
+ static inline u32 sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
+ {
+       if (ch->iostart)
+@@ -849,6 +851,7 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
+                               unsigned int hwidx, bool clockevent,
+                               bool clocksource, struct sh_cmt_device *cmt)
+ {
++      u32 value;
+       int ret;
+       /* Skip unused channels. */
+@@ -878,6 +881,11 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
+               ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
+               ch->ioctrl = ch->iostart + 0x10;
+               ch->timer_bit = 0;
++
++              /* Enable the clock supply to the channel */
++              value = ioread32(cmt->mapbase + CMCLKE);
++              value |= BIT(hwidx);
++              iowrite32(value, cmt->mapbase + CMCLKE);
+               break;
+       }
+@@ -1010,12 +1018,10 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+       else
+               cmt->rate = clk_get_rate(cmt->clk) / 8;
+-      clk_disable(cmt->clk);
+-
+       /* Map the memory resource(s). */
+       ret = sh_cmt_map_memory(cmt);
+       if (ret < 0)
+-              goto err_clk_unprepare;
++              goto err_clk_disable;
+       /* Allocate and setup the channels. */
+       cmt->num_channels = hweight8(cmt->hw_channels);
+@@ -1043,6 +1049,8 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+               mask &= ~(1 << hwidx);
+       }
++      clk_disable(cmt->clk);
++
+       platform_set_drvdata(pdev, cmt);
+       return 0;
+@@ -1050,6 +1058,8 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+ err_unmap:
+       kfree(cmt->channels);
+       iounmap(cmt->mapbase);
++err_clk_disable:
++      clk_disable(cmt->clk);
+ err_clk_unprepare:
+       clk_unprepare(cmt->clk);
+ err_clk_put:
+-- 
+2.35.1
+
diff --git a/queue-5.10/clocksource-drivers-timer-ti-dm-fix-missing-clk_disa.patch b/queue-5.10/clocksource-drivers-timer-ti-dm-fix-missing-clk_disa.patch
new file mode 100644 (file)
index 0000000..1e0f073
--- /dev/null
@@ -0,0 +1,43 @@
+From 1d0e272c14936d86a0f8485b1bcdb48cbe5a7af3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Oct 2022 19:44:27 +0800
+Subject: clocksource/drivers/timer-ti-dm: Fix missing clk_disable_unprepare in
+ dmtimer_systimer_init_clock()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 180d35a7c05d520314a590c99ad8643d0213f28b ]
+
+If clk_get_rate() fails which is called after clk_prepare_enable(),
+clk_disable_unprepare() need be called in error path to disable the
+clock in dmtimer_systimer_init_clock().
+
+Fixes: 52762fbd1c47 ("clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Tony Lindgren <tony@atomide.com>
+Link: https://lore.kernel.org/r/20221029114427.946520-1-yangyingliang@huawei.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clocksource/timer-ti-dm-systimer.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c
+index 2737407ff069..632523c1232f 100644
+--- a/drivers/clocksource/timer-ti-dm-systimer.c
++++ b/drivers/clocksource/timer-ti-dm-systimer.c
+@@ -345,8 +345,10 @@ static int __init dmtimer_systimer_init_clock(struct dmtimer_systimer *t,
+               return error;
+       r = clk_get_rate(clock);
+-      if (!r)
++      if (!r) {
++              clk_disable_unprepare(clock);
+               return -ENODEV;
++      }
+       if (is_ick)
+               t->ick = clock;
+-- 
+2.35.1
+
diff --git a/queue-5.10/configfs-fix-possible-memory-leak-in-configfs_create.patch b/queue-5.10/configfs-fix-possible-memory-leak-in-configfs_create.patch
new file mode 100644 (file)
index 0000000..5aeafc9
--- /dev/null
@@ -0,0 +1,102 @@
+From 75c2da48802b7ebe0ff5fd61dbac25be7f1fbb90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Oct 2022 09:42:30 +0800
+Subject: configfs: fix possible memory leak in configfs_create_dir()
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit c65234b283a65cfbfc94619655e820a5e55199eb ]
+
+kmemleak reported memory leaks in configfs_create_dir():
+
+unreferenced object 0xffff888009f6af00 (size 192):
+  comm "modprobe", pid 3777, jiffies 4295537735 (age 233.784s)
+  backtrace:
+    kmem_cache_alloc (mm/slub.c:3250 mm/slub.c:3256 mm/slub.c:3263 mm/slub.c:3273)
+    new_fragment (./include/linux/slab.h:600 fs/configfs/dir.c:163)
+    configfs_register_subsystem (fs/configfs/dir.c:1857)
+    basic_write (drivers/hwtracing/stm/p_basic.c:14) stm_p_basic
+    do_one_initcall (init/main.c:1296)
+    do_init_module (kernel/module/main.c:2455)
+    ...
+
+unreferenced object 0xffff888003ba7180 (size 96):
+  comm "modprobe", pid 3777, jiffies 4295537735 (age 233.784s)
+  backtrace:
+    kmem_cache_alloc (mm/slub.c:3250 mm/slub.c:3256 mm/slub.c:3263 mm/slub.c:3273)
+    configfs_new_dirent (./include/linux/slab.h:723 fs/configfs/dir.c:194)
+    configfs_make_dirent (fs/configfs/dir.c:248)
+    configfs_create_dir (fs/configfs/dir.c:296)
+    configfs_attach_group.isra.28 (fs/configfs/dir.c:816 fs/configfs/dir.c:852)
+    configfs_register_subsystem (fs/configfs/dir.c:1881)
+    basic_write (drivers/hwtracing/stm/p_basic.c:14) stm_p_basic
+    do_one_initcall (init/main.c:1296)
+    do_init_module (kernel/module/main.c:2455)
+    ...
+
+This is because the refcount is not correct in configfs_make_dirent().
+For normal stage, the refcount is changing as:
+
+configfs_register_subsystem()
+  configfs_create_dir()
+    configfs_make_dirent()
+      configfs_new_dirent() # set s_count = 1
+      dentry->d_fsdata = configfs_get(sd); # s_count = 2
+...
+configfs_unregister_subsystem()
+  configfs_remove_dir()
+    remove_dir()
+      configfs_remove_dirent() # s_count = 1
+    dput() ...
+      *dentry_unlink_inode()*
+        configfs_d_iput() # s_count = 0, release
+
+However, if we failed in configfs_create():
+
+configfs_register_subsystem()
+  configfs_create_dir()
+    configfs_make_dirent() # s_count = 2
+    ...
+    configfs_create() # fail
+    ->out_remove:
+    configfs_remove_dirent(dentry)
+      configfs_put(sd) # s_count = 1
+      return PTR_ERR(inode);
+
+There is no inode in the error path, so the configfs_d_iput() is lost
+and makes sd and fragment memory leaked.
+
+To fix this, when we failed in configfs_create(), manually call
+configfs_put(sd) to keep the refcount correct.
+
+Fixes: 7063fbf22611 ("[PATCH] configfs: User-driven configuration filesystem")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/configfs/dir.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
+index 5ad27e484014..12388ed4faa5 100644
+--- a/fs/configfs/dir.c
++++ b/fs/configfs/dir.c
+@@ -317,6 +317,7 @@ static int configfs_create_dir(struct config_item *item, struct dentry *dentry,
+       return 0;
+ out_remove:
++      configfs_put(dentry->d_fsdata);
+       configfs_remove_dirent(dentry);
+       return PTR_ERR(inode);
+ }
+@@ -383,6 +384,7 @@ int configfs_create_link(struct configfs_dirent *target, struct dentry *parent,
+       return 0;
+ out_remove:
++      configfs_put(dentry->d_fsdata);
+       configfs_remove_dirent(dentry);
+       return PTR_ERR(inode);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/counter-stm32-lptimer-cnt-fix-the-check-on-arr-and-c.patch b/queue-5.10/counter-stm32-lptimer-cnt-fix-the-check-on-arr-and-c.patch
new file mode 100644 (file)
index 0000000..b529615
--- /dev/null
@@ -0,0 +1,42 @@
+From d770f1d99097d7ae3aee81ca0ef9a4b881f868aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 14:36:09 +0100
+Subject: counter: stm32-lptimer-cnt: fix the check on arr and cmp registers
+ update
+
+From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+
+[ Upstream commit fd5ac974fc25feed084c2d1599d0dddb4e0556bc ]
+
+The ARR (auto reload register) and CMP (compare) registers are
+successively written. The status bits to check the update of these
+registers are polled together with regmap_read_poll_timeout().
+The condition to end the loop may become true, even if one of the register
+isn't correctly updated.
+So ensure both status bits are set before clearing them.
+
+Fixes: d8958824cf07 ("iio: counter: Add support for STM32 LPTimer")
+Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Link: https://lore.kernel.org/r/20221123133609.465614-1-fabrice.gasnier@foss.st.com/
+Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/counter/stm32-lptimer-cnt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
+index 937439635d53..b084e971a493 100644
+--- a/drivers/counter/stm32-lptimer-cnt.c
++++ b/drivers/counter/stm32-lptimer-cnt.c
+@@ -69,7 +69,7 @@ static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv,
+       /* ensure CMP & ARR registers are properly written */
+       ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
+-                                     (val & STM32_LPTIM_CMPOK_ARROK),
++                                     (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
+                                      100, 1000);
+       if (ret)
+               return ret;
+-- 
+2.35.1
+
diff --git a/queue-5.10/cpu-hotplug-make-target_store-a-nop-when-target-stat.patch b/queue-5.10/cpu-hotplug-make-target_store-a-nop-when-target-stat.patch
new file mode 100644 (file)
index 0000000..9e5805d
--- /dev/null
@@ -0,0 +1,60 @@
+From 92b983c9500481b5456123492c7eeae4790842f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 11:23:28 -0500
+Subject: cpu/hotplug: Make target_store() a nop when target == state
+
+From: Phil Auld <pauld@redhat.com>
+
+[ Upstream commit 64ea6e44f85b9b75925ebe1ba0e6e8430cc4e06f ]
+
+Writing the current state back in hotplug/target calls cpu_down()
+which will set cpu dying even when it isn't and then nothing will
+ever clear it. A stress test that reads values and writes them back
+for all cpu device files in sysfs will trigger the BUG() in
+select_fallback_rq once all cpus are marked as dying.
+
+kernel/cpu.c::target_store()
+       ...
+        if (st->state < target)
+                ret = cpu_up(dev->id, target);
+        else
+                ret = cpu_down(dev->id, target);
+
+cpu_down() -> cpu_set_state()
+        bool bringup = st->state < target;
+        ...
+        if (cpu_dying(cpu) != !bringup)
+               set_cpu_dying(cpu, !bringup);
+
+Fix this by letting state==target fall through in the target_store()
+conditional. Also make sure st->target == target in that case.
+
+Fixes: 757c989b9994 ("cpu/hotplug: Make target state writeable")
+Signed-off-by: Phil Auld <pauld@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Link: https://lore.kernel.org/r/20221117162329.3164999-2-pauld@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/cpu.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index 3c9ee966c56a..008b50da2224 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -2231,8 +2231,10 @@ static ssize_t write_cpuhp_target(struct device *dev,
+       if (st->state < target)
+               ret = cpu_up(dev->id, target);
+-      else
++      else if (st->state > target)
+               ret = cpu_down(dev->id, target);
++      else if (WARN_ON(st->target != target))
++              st->target = target;
+ out:
+       unlock_device_hotplug();
+       return ret ? ret : count;
+-- 
+2.35.1
+
diff --git a/queue-5.10/cpufreq-amd_freq_sensitivity-add-missing-pci_dev_put.patch b/queue-5.10/cpufreq-amd_freq_sensitivity-add-missing-pci_dev_put.patch
new file mode 100644 (file)
index 0000000..cf51d48
--- /dev/null
@@ -0,0 +1,37 @@
+From a00a4db924dda8debcd26afb0bc989b73992b05d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 19:33:39 +0800
+Subject: cpufreq: amd_freq_sensitivity: Add missing pci_dev_put()
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit 91fda1f88c0968f1491ab150bb01690525af150a ]
+
+pci_get_device() will increase the reference count for the returned
+pci_dev. We need to use pci_dev_put() to decrease the reference count
+after using pci_get_device(). Let's add it.
+
+Fixes: 59a3b3a8db16 ("cpufreq: AMD: Ignore the check for ProcFeedback in ST/CZ")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/amd_freq_sensitivity.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c
+index d0b10baf039a..151771129c7b 100644
+--- a/drivers/cpufreq/amd_freq_sensitivity.c
++++ b/drivers/cpufreq/amd_freq_sensitivity.c
+@@ -124,6 +124,8 @@ static int __init amd_freq_sensitivity_init(void)
+       if (!pcidev) {
+               if (!boot_cpu_has(X86_FEATURE_PROC_FEEDBACK))
+                       return -ENODEV;
++      } else {
++              pci_dev_put(pcidev);
+       }
+       if (rdmsrl_safe(MSR_AMD64_FREQ_SENSITIVITY_ACTUAL, &val))
+-- 
+2.35.1
+
diff --git a/queue-5.10/cpufreq-qcom-hw-fix-memory-leak-in-qcom_cpufreq_hw_r.patch b/queue-5.10/cpufreq-qcom-hw-fix-memory-leak-in-qcom_cpufreq_hw_r.patch
new file mode 100644 (file)
index 0000000..9953a9c
--- /dev/null
@@ -0,0 +1,36 @@
+From f1b1248b9e620e89756c5904c2d62cf35c843ad8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 15:23:02 +0800
+Subject: cpufreq: qcom-hw: Fix memory leak in qcom_cpufreq_hw_read_lut()
+
+From: Chen Hui <judy.chenhui@huawei.com>
+
+[ Upstream commit 9901c21bcaf2f01fe5078f750d624f4ddfa8f81b ]
+
+If "cpu_dev" fails to get opp table in qcom_cpufreq_hw_read_lut(),
+the program will return, resulting in "table" resource is not released.
+
+Fixes: 51c843cf77bb ("cpufreq: qcom: Update the bandwidth levels on frequency change")
+Signed-off-by: Chen Hui <judy.chenhui@huawei.com>
+Reviewed-by: Sibi Sankar <quic_sibis@quicinc.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/qcom-cpufreq-hw.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
+index 6de07556665b..a9880998f8ba 100644
+--- a/drivers/cpufreq/qcom-cpufreq-hw.c
++++ b/drivers/cpufreq/qcom-cpufreq-hw.c
+@@ -158,6 +158,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
+               }
+       } else if (ret != -ENODEV) {
+               dev_err(cpu_dev, "Invalid opp table in device tree\n");
++              kfree(table);
+               return ret;
+       } else {
+               policy->fast_switch_possible = true;
+-- 
+2.35.1
+
diff --git a/queue-5.10/cpuidle-dt-return-the-correct-numbers-of-parsed-idle.patch b/queue-5.10/cpuidle-dt-return-the-correct-numbers-of-parsed-idle.patch
new file mode 100644 (file)
index 0000000..39939f9
--- /dev/null
@@ -0,0 +1,44 @@
+From 62f7c93c6f8cae08b04f12b4f6990d489837ae21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Oct 2022 17:10:12 +0200
+Subject: cpuidle: dt: Return the correct numbers of parsed idle states
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit ee3c2c8ad6ba6785f14a60e4081d7c82e88162a2 ]
+
+While we correctly skips to initialize an idle state from a disabled idle
+state node in DT, the returned value from dt_init_idle_driver() don't get
+adjusted accordingly. Instead the number of found idle state nodes are
+returned, while the callers are expecting the number of successfully
+initialized idle states from DT.
+
+This leads to cpuidle drivers unnecessarily continues to initialize their
+idle state specific data. Moreover, in the case when all idle states have
+been disabled in DT, we would end up registering a cpuidle driver, rather
+than relying on the default arch specific idle call.
+
+Fixes: 9f14da345599 ("drivers: cpuidle: implement DT based idle states infrastructure")
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/dt_idle_states.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c
+index 252f2a9686a6..448bc796b0b4 100644
+--- a/drivers/cpuidle/dt_idle_states.c
++++ b/drivers/cpuidle/dt_idle_states.c
+@@ -223,6 +223,6 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,
+        * also be 0 on platforms with missing DT idle states or legacy DT
+        * configuration predating the DT idle states bindings.
+        */
+-      return i;
++      return state_idx - start_idx;
+ }
+ EXPORT_SYMBOL_GPL(dt_init_idle_driver);
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-amlogic-remove-kcalloc-without-check.patch b/queue-5.10/crypto-amlogic-remove-kcalloc-without-check.patch
new file mode 100644 (file)
index 0000000..f2c4208
--- /dev/null
@@ -0,0 +1,53 @@
+From e757f1f398627afa884dd1cf0e760b92950bb9b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 22:56:19 +0100
+Subject: crypto: amlogic - Remove kcalloc without check
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 3d780c8a9850ad60dee47a8d971ba7888f3d1bd3 ]
+
+There is no real point in allocating dedicated memory for the irqs array.
+MAXFLOW is only 2, so it is easier to allocated the needed space
+directly within the 'meson_dev' structure.
+
+This saves some memory allocation and avoids an indirection when using the
+irqs array.
+
+Fixes: 48fe583fe541 ("crypto: amlogic - Add crypto accelerator...")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/amlogic/amlogic-gxl-core.c | 1 -
+ drivers/crypto/amlogic/amlogic-gxl.h      | 2 +-
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
+index 5bbeff433c8c..7a5cf1122af9 100644
+--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
++++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
+@@ -240,7 +240,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
+               return err;
+       }
+-      mc->irqs = devm_kcalloc(mc->dev, MAXFLOW, sizeof(int), GFP_KERNEL);
+       for (i = 0; i < MAXFLOW; i++) {
+               mc->irqs[i] = platform_get_irq(pdev, i);
+               if (mc->irqs[i] < 0)
+diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
+index dc0f142324a3..8c0746a1d6d4 100644
+--- a/drivers/crypto/amlogic/amlogic-gxl.h
++++ b/drivers/crypto/amlogic/amlogic-gxl.h
+@@ -95,7 +95,7 @@ struct meson_dev {
+       struct device *dev;
+       struct meson_flow *chanlist;
+       atomic_t flow;
+-      int *irqs;
++      int irqs[MAXFLOW];
+ #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+       struct dentry *dbgfs_dir;
+ #endif
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-ccree-make-cc_debugfs_global_fini-available-f.patch b/queue-5.10/crypto-ccree-make-cc_debugfs_global_fini-available-f.patch
new file mode 100644 (file)
index 0000000..b822eb8
--- /dev/null
@@ -0,0 +1,46 @@
+From c02d3707678947a8a378dc7a9e22ed884502145b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 18:22:36 +0100
+Subject: crypto: ccree - Make cc_debugfs_global_fini() available for module
+ init function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 8e96729fc26c8967db45a3fb7a60387619f77a22 ]
+
+ccree_init() calls cc_debugfs_global_fini(), the former is an init
+function and the latter an exit function though.
+
+A modular build emits:
+
+       WARNING: modpost: drivers/crypto/ccree/ccree.o: section mismatch in reference: init_module (section: .init.text) -> cc_debugfs_global_fini (section: .exit.text)
+
+(with CONFIG_DEBUG_SECTION_MISMATCH=y).
+
+Fixes: 4f1c596df706 ("crypto: ccree - Remove debugfs when platform_driver_register failed")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccree/cc_debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/ccree/cc_debugfs.c b/drivers/crypto/ccree/cc_debugfs.c
+index 7083767602fc..8f008f024f8f 100644
+--- a/drivers/crypto/ccree/cc_debugfs.c
++++ b/drivers/crypto/ccree/cc_debugfs.c
+@@ -55,7 +55,7 @@ void __init cc_debugfs_global_init(void)
+       cc_debugfs_dir = debugfs_create_dir("ccree", NULL);
+ }
+-void __exit cc_debugfs_global_fini(void)
++void cc_debugfs_global_fini(void)
+ {
+       debugfs_remove(cc_debugfs_dir);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-ccree-remove-debugfs-when-platform_driver_reg.patch b/queue-5.10/crypto-ccree-remove-debugfs-when-platform_driver_reg.patch
new file mode 100644 (file)
index 0000000..f7d952d
--- /dev/null
@@ -0,0 +1,49 @@
+From 0f36c57bf9339d70053c4ab857032f136d98afd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 16:29:12 +0800
+Subject: crypto: ccree - Remove debugfs when platform_driver_register failed
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 4f1c596df706c9aca662b6c214fad84047ae2a97 ]
+
+When platform_driver_register failed, we need to remove debugfs,
+which will caused a resource leak, fix it.
+
+Failed logs as follows:
+[   32.606488] debugfs: Directory 'ccree' with parent '/' already present!
+
+Fixes: 4c3f97276e15 ("crypto: ccree - introduce CryptoCell driver")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccree/cc_driver.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/ccree/cc_driver.c b/drivers/crypto/ccree/cc_driver.c
+index 6f519d3e896c..7924693f58e0 100644
+--- a/drivers/crypto/ccree/cc_driver.c
++++ b/drivers/crypto/ccree/cc_driver.c
+@@ -614,9 +614,17 @@ static struct platform_driver ccree_driver = {
+ static int __init ccree_init(void)
+ {
++      int rc;
++
+       cc_debugfs_global_init();
+-      return platform_driver_register(&ccree_driver);
++      rc = platform_driver_register(&ccree_driver);
++      if (rc) {
++              cc_debugfs_global_fini();
++              return rc;
++      }
++
++      return 0;
+ }
+ module_init(ccree_init);
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-cryptd-use-request-context-instead-of-stack-f.patch b/queue-5.10/crypto-cryptd-use-request-context-instead-of-stack-f.patch
new file mode 100644 (file)
index 0000000..d67cc24
--- /dev/null
@@ -0,0 +1,128 @@
+From 949508896034b00f581c526bc2142cfb311713db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 17:59:17 +0800
+Subject: crypto: cryptd - Use request context instead of stack for sub-request
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 3a58c231172537f7b0e19d93ed33decd04f80eab ]
+
+cryptd is buggy as it tries to use sync_skcipher without going
+through the proper sync_skcipher interface.  In fact it doesn't
+even need sync_skcipher since it's already a proper skcipher and
+can easily access the request context instead of using something
+off the stack.
+
+Fixes: 36b3875a97b8 ("crypto: cryptd - Remove VLA usage of skcipher")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/cryptd.c | 36 +++++++++++++++++++-----------------
+ 1 file changed, 19 insertions(+), 17 deletions(-)
+
+diff --git a/crypto/cryptd.c b/crypto/cryptd.c
+index 668095eca0fa..ca3a40fc7da9 100644
+--- a/crypto/cryptd.c
++++ b/crypto/cryptd.c
+@@ -68,11 +68,12 @@ struct aead_instance_ctx {
+ struct cryptd_skcipher_ctx {
+       refcount_t refcnt;
+-      struct crypto_sync_skcipher *child;
++      struct crypto_skcipher *child;
+ };
+ struct cryptd_skcipher_request_ctx {
+       crypto_completion_t complete;
++      struct skcipher_request req;
+ };
+ struct cryptd_hash_ctx {
+@@ -227,13 +228,13 @@ static int cryptd_skcipher_setkey(struct crypto_skcipher *parent,
+                                 const u8 *key, unsigned int keylen)
+ {
+       struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(parent);
+-      struct crypto_sync_skcipher *child = ctx->child;
++      struct crypto_skcipher *child = ctx->child;
+-      crypto_sync_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+-      crypto_sync_skcipher_set_flags(child,
+-                                     crypto_skcipher_get_flags(parent) &
+-                                       CRYPTO_TFM_REQ_MASK);
+-      return crypto_sync_skcipher_setkey(child, key, keylen);
++      crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
++      crypto_skcipher_set_flags(child,
++                                crypto_skcipher_get_flags(parent) &
++                                CRYPTO_TFM_REQ_MASK);
++      return crypto_skcipher_setkey(child, key, keylen);
+ }
+ static void cryptd_skcipher_complete(struct skcipher_request *req, int err)
+@@ -258,13 +259,13 @@ static void cryptd_skcipher_encrypt(struct crypto_async_request *base,
+       struct cryptd_skcipher_request_ctx *rctx = skcipher_request_ctx(req);
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+-      struct crypto_sync_skcipher *child = ctx->child;
+-      SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, child);
++      struct skcipher_request *subreq = &rctx->req;
++      struct crypto_skcipher *child = ctx->child;
+       if (unlikely(err == -EINPROGRESS))
+               goto out;
+-      skcipher_request_set_sync_tfm(subreq, child);
++      skcipher_request_set_tfm(subreq, child);
+       skcipher_request_set_callback(subreq, CRYPTO_TFM_REQ_MAY_SLEEP,
+                                     NULL, NULL);
+       skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
+@@ -286,13 +287,13 @@ static void cryptd_skcipher_decrypt(struct crypto_async_request *base,
+       struct cryptd_skcipher_request_ctx *rctx = skcipher_request_ctx(req);
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+-      struct crypto_sync_skcipher *child = ctx->child;
+-      SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, child);
++      struct skcipher_request *subreq = &rctx->req;
++      struct crypto_skcipher *child = ctx->child;
+       if (unlikely(err == -EINPROGRESS))
+               goto out;
+-      skcipher_request_set_sync_tfm(subreq, child);
++      skcipher_request_set_tfm(subreq, child);
+       skcipher_request_set_callback(subreq, CRYPTO_TFM_REQ_MAY_SLEEP,
+                                     NULL, NULL);
+       skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
+@@ -343,9 +344,10 @@ static int cryptd_skcipher_init_tfm(struct crypto_skcipher *tfm)
+       if (IS_ERR(cipher))
+               return PTR_ERR(cipher);
+-      ctx->child = (struct crypto_sync_skcipher *)cipher;
++      ctx->child = cipher;
+       crypto_skcipher_set_reqsize(
+-              tfm, sizeof(struct cryptd_skcipher_request_ctx));
++              tfm, sizeof(struct cryptd_skcipher_request_ctx) +
++                   crypto_skcipher_reqsize(cipher));
+       return 0;
+ }
+@@ -353,7 +355,7 @@ static void cryptd_skcipher_exit_tfm(struct crypto_skcipher *tfm)
+ {
+       struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+-      crypto_free_sync_skcipher(ctx->child);
++      crypto_free_skcipher(ctx->child);
+ }
+ static void cryptd_skcipher_free(struct skcipher_instance *inst)
+@@ -931,7 +933,7 @@ struct crypto_skcipher *cryptd_skcipher_child(struct cryptd_skcipher *tfm)
+ {
+       struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(&tfm->base);
+-      return &ctx->child->base;
++      return ctx->child;
+ }
+ EXPORT_SYMBOL_GPL(cryptd_skcipher_child);
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-hisilicon-qm-add-missing-pci_dev_put-in-q_num.patch b/queue-5.10/crypto-hisilicon-qm-add-missing-pci_dev_put-in-q_num.patch
new file mode 100644 (file)
index 0000000..c7bb561
--- /dev/null
@@ -0,0 +1,55 @@
+From fff290a60ec33774c34a739993394de294e54cc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 18:00:36 +0800
+Subject: crypto: hisilicon/qm - add missing pci_dev_put() in q_num_set()
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit cc7710d0d4ebc6998f04035cde4f32c5ddbe9d7f ]
+
+pci_get_device() will increase the reference count for the returned
+pci_dev. We need to use pci_dev_put() to decrease the reference count
+before q_num_set() returns.
+
+Fixes: c8b4b477079d ("crypto: hisilicon - add HiSilicon HPRE accelerator")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Reviewed-by: Weili Qian <qianweili@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/qm.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h
+index 0420f4ce7197..aaad3d76dc04 100644
+--- a/drivers/crypto/hisilicon/qm.h
++++ b/drivers/crypto/hisilicon/qm.h
+@@ -289,14 +289,14 @@ struct hisi_qp {
+ static inline int q_num_set(const char *val, const struct kernel_param *kp,
+                           unsigned int device)
+ {
+-      struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI,
+-                                            device, NULL);
++      struct pci_dev *pdev;
+       u32 n, q_num;
+       int ret;
+       if (!val)
+               return -EINVAL;
++      pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI, device, NULL);
+       if (!pdev) {
+               q_num = min_t(u32, QM_QNUM_V1, QM_QNUM_V2);
+               pr_info("No device found currently, suppose queue number is %d\n",
+@@ -306,6 +306,8 @@ static inline int q_num_set(const char *val, const struct kernel_param *kp,
+                       q_num = QM_QNUM_V1;
+               else
+                       q_num = QM_QNUM_V2;
++
++              pci_dev_put(pdev);
+       }
+       ret = kstrtou32(val, 10, &n);
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-img-hash-fix-variable-dereferenced-before-che.patch b/queue-5.10/crypto-img-hash-fix-variable-dereferenced-before-che.patch
new file mode 100644 (file)
index 0000000..c5186af
--- /dev/null
@@ -0,0 +1,52 @@
+From a794d26f18b9bf5808df393c7acc3c0379cad95c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 14:25:26 +0800
+Subject: crypto: img-hash - Fix variable dereferenced before check 'hdev->req'
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 04ba54e5af8f8f0137b08cb51a0b3a2e1ea46c94 ]
+
+Smatch report warning as follows:
+
+drivers/crypto/img-hash.c:366 img_hash_dma_task() warn: variable
+dereferenced before check 'hdev->req'
+
+Variable dereferenced should be done after check 'hdev->req',
+fix it.
+
+Fixes: d358f1abbf71 ("crypto: img-hash - Add Imagination Technologies hw hash accelerator")
+Fixes: 10badea259fa ("crypto: img-hash - Fix null pointer exception")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/img-hash.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/img-hash.c b/drivers/crypto/img-hash.c
+index 91f555ccbb31..cecae50d0f58 100644
+--- a/drivers/crypto/img-hash.c
++++ b/drivers/crypto/img-hash.c
+@@ -357,12 +357,16 @@ static int img_hash_dma_init(struct img_hash_dev *hdev)
+ static void img_hash_dma_task(unsigned long d)
+ {
+       struct img_hash_dev *hdev = (struct img_hash_dev *)d;
+-      struct img_hash_request_ctx *ctx = ahash_request_ctx(hdev->req);
++      struct img_hash_request_ctx *ctx;
+       u8 *addr;
+       size_t nbytes, bleft, wsend, len, tbc;
+       struct scatterlist tsg;
+-      if (!hdev->req || !ctx->sg)
++      if (!hdev->req)
++              return;
++
++      ctx = ahash_request_ctx(hdev->req);
++      if (!ctx->sg)
+               return;
+       addr = sg_virt(ctx->sg);
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-nitrox-avoid-double-free-on-error-path-in-nit.patch b/queue-5.10/crypto-nitrox-avoid-double-free-on-error-path-in-nit.patch
new file mode 100644 (file)
index 0000000..247e2b3
--- /dev/null
@@ -0,0 +1,43 @@
+From b25a6019ba9380056eda33c1c209788173378624 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Sep 2022 13:25:05 +0300
+Subject: crypto: nitrox - avoid double free on error path in
+ nitrox_sriov_init()
+
+From: Natalia Petrova <n.petrova@fintech.ru>
+
+[ Upstream commit 094528b6a5a755b1195a01e10b13597d67d1a0e6 ]
+
+If alloc_workqueue() fails in nitrox_mbox_init() it deallocates
+ndev->iov.vfdev and returns error code, but then nitrox_sriov_init()
+calls nitrox_sriov_cleanup() where ndev->iov.vfdev is deallocated
+again.
+
+Fix this by nulling ndev->iov.vfdev after the first deallocation.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 9e5de3e06e54 ("crypto: cavium/nitrox - Add mailbox...")
+Signed-off-by: Natalia Petrova <n.petrova@fintech.ru>
+Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/cavium/nitrox/nitrox_mbx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/crypto/cavium/nitrox/nitrox_mbx.c b/drivers/crypto/cavium/nitrox/nitrox_mbx.c
+index b51b0449b478..a131dbbbcb86 100644
+--- a/drivers/crypto/cavium/nitrox/nitrox_mbx.c
++++ b/drivers/crypto/cavium/nitrox/nitrox_mbx.c
+@@ -190,6 +190,7 @@ int nitrox_mbox_init(struct nitrox_device *ndev)
+       ndev->iov.pf2vf_wq = alloc_workqueue("nitrox_pf2vf", 0, 0);
+       if (!ndev->iov.pf2vf_wq) {
+               kfree(ndev->iov.vfdev);
++              ndev->iov.vfdev = NULL;
+               return -ENOMEM;
+       }
+       /* enable pf2vf mailbox interrupts */
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-omap-sham-use-pm_runtime_resume_and_get-in-om.patch b/queue-5.10/crypto-omap-sham-use-pm_runtime_resume_and_get-in-om.patch
new file mode 100644 (file)
index 0000000..7019498
--- /dev/null
@@ -0,0 +1,41 @@
+From 7b884c71bdcff10128094af70511fab9f5ab4d73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Nov 2022 14:49:40 +0800
+Subject: crypto: omap-sham - Use pm_runtime_resume_and_get() in
+ omap_sham_probe()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit 7bcceb4c9896b1b672b636ae70fe75110d6bf1ad ]
+
+omap_sham_probe() calls pm_runtime_get_sync() and calls
+pm_runtime_put_sync() latter to put usage_counter. However,
+pm_runtime_get_sync() will increment usage_counter even it failed. Fix
+it by replacing it with pm_runtime_resume_and_get() to keep usage
+counter balanced.
+
+Fixes: b359f034c8bf ("crypto: omap-sham - Convert to use pm_runtime API")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.com>
+Acked-by: Mark Greer <mgreer@animalcreek.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/omap-sham.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
+index 48f78e34cf8d..5a57617441b8 100644
+--- a/drivers/crypto/omap-sham.c
++++ b/drivers/crypto/omap-sham.c
+@@ -2130,7 +2130,7 @@ static int omap_sham_probe(struct platform_device *pdev)
+       pm_runtime_enable(dev);
+       pm_runtime_irq_safe(dev);
+-      err = pm_runtime_get_sync(dev);
++      err = pm_runtime_resume_and_get(dev);
+       if (err < 0) {
+               dev_err(dev, "failed to get sync: %d\n", err);
+               goto err_pm;
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-rockchip-add-fallback-for-ahash.patch b/queue-5.10/crypto-rockchip-add-fallback-for-ahash.patch
new file mode 100644 (file)
index 0000000..907e591
--- /dev/null
@@ -0,0 +1,86 @@
+From 4059e8312404550c2703faaa1d7ea3ebb5c09f70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Sep 2022 07:54:45 +0000
+Subject: crypto: rockchip - add fallback for ahash
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit 816600485cb597b3ff7d6806a95a78512839f775 ]
+
+Adds a fallback for all case hardware cannot handle.
+
+Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
+Reviewed-by: John Keeping <john@metanate.com>
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/rockchip/rk3288_crypto_ahash.c | 38 +++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+index 9583310a69d5..f917adc4a608 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+@@ -16,6 +16,40 @@
+  * so we put the fixed hash out when met zero message.
+  */
++static bool rk_ahash_need_fallback(struct ahash_request *req)
++{
++      struct scatterlist *sg;
++
++      sg = req->src;
++      while (sg) {
++              if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
++                      return true;
++              }
++              if (sg->length % 4) {
++                      return true;
++              }
++              sg = sg_next(sg);
++      }
++      return false;
++}
++
++static int rk_ahash_digest_fb(struct ahash_request *areq)
++{
++      struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++      struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++      struct rk_ahash_ctx *tfmctx = crypto_ahash_ctx(tfm);
++
++      ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
++      rctx->fallback_req.base.flags = areq->base.flags &
++                                      CRYPTO_TFM_REQ_MAY_SLEEP;
++
++      rctx->fallback_req.nbytes = areq->nbytes;
++      rctx->fallback_req.src = areq->src;
++      rctx->fallback_req.result = areq->result;
++
++      return crypto_ahash_digest(&rctx->fallback_req);
++}
++
+ static int zero_message_process(struct ahash_request *req)
+ {
+       struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+@@ -167,6 +201,9 @@ static int rk_ahash_digest(struct ahash_request *req)
+       struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
+       struct rk_crypto_info *dev = tctx->dev;
++      if (rk_ahash_need_fallback(req))
++              return rk_ahash_digest_fb(req);
++
+       if (!req->nbytes)
+               return zero_message_process(req);
+       else
+@@ -309,6 +346,7 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
+       struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);
+       free_page((unsigned long)tctx->dev->addr_vir);
++      crypto_free_ahash(tctx->fallback_tfm);
+ }
+ struct rk_crypto_tmp rk_ahash_sha1 = {
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-rockchip-add-fallback-for-cipher.patch b/queue-5.10/crypto-rockchip-add-fallback-for-cipher.patch
new file mode 100644 (file)
index 0000000..7c8d873
--- /dev/null
@@ -0,0 +1,259 @@
+From 69a34d986daca1abee8e593d20507b85a2b547d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Sep 2022 07:54:44 +0000
+Subject: crypto: rockchip - add fallback for cipher
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit 68ef8af09a1a912a5ed2cfaa4cca7606f52cef90 ]
+
+The hardware does not handle 0 size length request, let's add a
+fallback.
+Furthermore fallback will be used for all unaligned case the hardware
+cannot handle.
+
+Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
+Reviewed-by: John Keeping <john@metanate.com>
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/Kconfig                        |  4 +
+ drivers/crypto/rockchip/rk3288_crypto.h       |  2 +
+ .../crypto/rockchip/rk3288_crypto_skcipher.c  | 97 ++++++++++++++++---
+ 3 files changed, 90 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
+index ff5e85eefbf6..8aa8b330df70 100644
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -749,6 +749,10 @@ config CRYPTO_DEV_IMGTEC_HASH
+ config CRYPTO_DEV_ROCKCHIP
+       tristate "Rockchip's Cryptographic Engine driver"
+       depends on OF && ARCH_ROCKCHIP
++      depends on PM
++      select CRYPTO_ECB
++      select CRYPTO_CBC
++      select CRYPTO_DES
+       select CRYPTO_AES
+       select CRYPTO_LIB_DES
+       select CRYPTO_MD5
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
+index 65b9b58bb304..027e28f60843 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.h
++++ b/drivers/crypto/rockchip/rk3288_crypto.h
+@@ -245,10 +245,12 @@ struct rk_cipher_ctx {
+       struct rk_crypto_info           *dev;
+       unsigned int                    keylen;
+       u8                              iv[AES_BLOCK_SIZE];
++      struct crypto_skcipher *fallback_tfm;
+ };
+ struct rk_cipher_rctx {
+       u32                             mode;
++      struct skcipher_request fallback_req;   // keep at the end
+ };
+ enum alg_type {
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+index bbd0bf52bf07..eac5bba66e25 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+@@ -13,6 +13,63 @@
+ #define RK_CRYPTO_DEC                 BIT(0)
++static int rk_cipher_need_fallback(struct skcipher_request *req)
++{
++      struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
++      unsigned int bs = crypto_skcipher_blocksize(tfm);
++      struct scatterlist *sgs, *sgd;
++      unsigned int stodo, dtodo, len;
++
++      if (!req->cryptlen)
++              return true;
++
++      len = req->cryptlen;
++      sgs = req->src;
++      sgd = req->dst;
++      while (sgs && sgd) {
++              if (!IS_ALIGNED(sgs->offset, sizeof(u32))) {
++                      return true;
++              }
++              if (!IS_ALIGNED(sgd->offset, sizeof(u32))) {
++                      return true;
++              }
++              stodo = min(len, sgs->length);
++              if (stodo % bs) {
++                      return true;
++              }
++              dtodo = min(len, sgd->length);
++              if (dtodo % bs) {
++                      return true;
++              }
++              if (stodo != dtodo) {
++                      return true;
++              }
++              len -= stodo;
++              sgs = sg_next(sgs);
++              sgd = sg_next(sgd);
++      }
++      return false;
++}
++
++static int rk_cipher_fallback(struct skcipher_request *areq)
++{
++      struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
++      struct rk_cipher_ctx *op = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq);
++      int err;
++
++      skcipher_request_set_tfm(&rctx->fallback_req, op->fallback_tfm);
++      skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags,
++                                    areq->base.complete, areq->base.data);
++      skcipher_request_set_crypt(&rctx->fallback_req, areq->src, areq->dst,
++                                 areq->cryptlen, areq->iv);
++      if (rctx->mode & RK_CRYPTO_DEC)
++              err = crypto_skcipher_decrypt(&rctx->fallback_req);
++      else
++              err = crypto_skcipher_encrypt(&rctx->fallback_req);
++      return err;
++}
++
+ static void rk_crypto_complete(struct crypto_async_request *base, int err)
+ {
+       if (base->complete)
+@@ -22,10 +79,10 @@ static void rk_crypto_complete(struct crypto_async_request *base, int err)
+ static int rk_handle_req(struct rk_crypto_info *dev,
+                        struct skcipher_request *req)
+ {
+-      if (!IS_ALIGNED(req->cryptlen, dev->align_size))
+-              return -EINVAL;
+-      else
+-              return dev->enqueue(dev, &req->base);
++      if (rk_cipher_need_fallback(req))
++              return rk_cipher_fallback(req);
++
++      return dev->enqueue(dev, &req->base);
+ }
+ static int rk_aes_setkey(struct crypto_skcipher *cipher,
+@@ -39,7 +96,8 @@ static int rk_aes_setkey(struct crypto_skcipher *cipher,
+               return -EINVAL;
+       ctx->keylen = keylen;
+       memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen);
+-      return 0;
++
++      return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+ static int rk_des_setkey(struct crypto_skcipher *cipher,
+@@ -54,7 +112,8 @@ static int rk_des_setkey(struct crypto_skcipher *cipher,
+       ctx->keylen = keylen;
+       memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
+-      return 0;
++
++      return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+ static int rk_tdes_setkey(struct crypto_skcipher *cipher,
+@@ -69,7 +128,7 @@ static int rk_tdes_setkey(struct crypto_skcipher *cipher,
+       ctx->keylen = keylen;
+       memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
+-      return 0;
++      return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+ static int rk_aes_ecb_encrypt(struct skcipher_request *req)
+@@ -394,6 +453,7 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
+ {
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
++      const char *name = crypto_tfm_alg_name(&tfm->base);
+       struct rk_crypto_tmp *algt;
+       algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
+@@ -407,6 +467,16 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
+       if (!ctx->dev->addr_vir)
+               return -ENOMEM;
++      ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
++      if (IS_ERR(ctx->fallback_tfm)) {
++              dev_err(ctx->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n",
++                      name, PTR_ERR(ctx->fallback_tfm));
++              return PTR_ERR(ctx->fallback_tfm);
++      }
++
++      tfm->reqsize = sizeof(struct rk_cipher_rctx) +
++              crypto_skcipher_reqsize(ctx->fallback_tfm);
++
+       return 0;
+ }
+@@ -415,6 +485,7 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       free_page((unsigned long)ctx->dev->addr_vir);
++      crypto_free_skcipher(ctx->fallback_tfm);
+ }
+ struct rk_crypto_tmp rk_ecb_aes_alg = {
+@@ -423,7 +494,7 @@ struct rk_crypto_tmp rk_ecb_aes_alg = {
+               .base.cra_name          = "ecb(aes)",
+               .base.cra_driver_name   = "ecb-aes-rk",
+               .base.cra_priority      = 300,
+-              .base.cra_flags         = CRYPTO_ALG_ASYNC,
++              .base.cra_flags         = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+               .base.cra_blocksize     = AES_BLOCK_SIZE,
+               .base.cra_ctxsize       = sizeof(struct rk_cipher_ctx),
+               .base.cra_alignmask     = 0x0f,
+@@ -445,7 +516,7 @@ struct rk_crypto_tmp rk_cbc_aes_alg = {
+               .base.cra_name          = "cbc(aes)",
+               .base.cra_driver_name   = "cbc-aes-rk",
+               .base.cra_priority      = 300,
+-              .base.cra_flags         = CRYPTO_ALG_ASYNC,
++              .base.cra_flags         = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+               .base.cra_blocksize     = AES_BLOCK_SIZE,
+               .base.cra_ctxsize       = sizeof(struct rk_cipher_ctx),
+               .base.cra_alignmask     = 0x0f,
+@@ -468,7 +539,7 @@ struct rk_crypto_tmp rk_ecb_des_alg = {
+               .base.cra_name          = "ecb(des)",
+               .base.cra_driver_name   = "ecb-des-rk",
+               .base.cra_priority      = 300,
+-              .base.cra_flags         = CRYPTO_ALG_ASYNC,
++              .base.cra_flags         = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+               .base.cra_blocksize     = DES_BLOCK_SIZE,
+               .base.cra_ctxsize       = sizeof(struct rk_cipher_ctx),
+               .base.cra_alignmask     = 0x07,
+@@ -490,7 +561,7 @@ struct rk_crypto_tmp rk_cbc_des_alg = {
+               .base.cra_name          = "cbc(des)",
+               .base.cra_driver_name   = "cbc-des-rk",
+               .base.cra_priority      = 300,
+-              .base.cra_flags         = CRYPTO_ALG_ASYNC,
++              .base.cra_flags         = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+               .base.cra_blocksize     = DES_BLOCK_SIZE,
+               .base.cra_ctxsize       = sizeof(struct rk_cipher_ctx),
+               .base.cra_alignmask     = 0x07,
+@@ -513,7 +584,7 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
+               .base.cra_name          = "ecb(des3_ede)",
+               .base.cra_driver_name   = "ecb-des3-ede-rk",
+               .base.cra_priority      = 300,
+-              .base.cra_flags         = CRYPTO_ALG_ASYNC,
++              .base.cra_flags         = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+               .base.cra_blocksize     = DES_BLOCK_SIZE,
+               .base.cra_ctxsize       = sizeof(struct rk_cipher_ctx),
+               .base.cra_alignmask     = 0x07,
+@@ -535,7 +606,7 @@ struct rk_crypto_tmp rk_cbc_des3_ede_alg = {
+               .base.cra_name          = "cbc(des3_ede)",
+               .base.cra_driver_name   = "cbc-des3-ede-rk",
+               .base.cra_priority      = 300,
+-              .base.cra_flags         = CRYPTO_ALG_ASYNC,
++              .base.cra_flags         = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+               .base.cra_blocksize     = DES_BLOCK_SIZE,
+               .base.cra_ctxsize       = sizeof(struct rk_cipher_ctx),
+               .base.cra_alignmask     = 0x07,
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-rockchip-better-handle-cipher-key.patch b/queue-5.10/crypto-rockchip-better-handle-cipher-key.patch
new file mode 100644 (file)
index 0000000..d996d17
--- /dev/null
@@ -0,0 +1,94 @@
+From b6286acf458839937c31781b6a5b08ffe798b4bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Sep 2022 07:54:46 +0000
+Subject: crypto: rockchip - better handle cipher key
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit d6b23ccef82816050c2fd458c9dabfa0e0af09b9 ]
+
+The key should not be set in hardware too much in advance, this will
+fail it 2 TFM with different keys generate alternative requests.
+The key should be stored and used just before doing cipher operations.
+
+Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
+Reviewed-by: John Keeping <john@metanate.com>
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/rockchip/rk3288_crypto.h          |  1 +
+ drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 10 +++++++---
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
+index 027e28f60843..1eabf3952a03 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.h
++++ b/drivers/crypto/rockchip/rk3288_crypto.h
+@@ -244,6 +244,7 @@ struct rk_ahash_rctx {
+ struct rk_cipher_ctx {
+       struct rk_crypto_info           *dev;
+       unsigned int                    keylen;
++      u8                              key[AES_MAX_KEY_SIZE];
+       u8                              iv[AES_BLOCK_SIZE];
+       struct crypto_skcipher *fallback_tfm;
+ };
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+index eac5bba66e25..1ef94f8db2c5 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+@@ -95,7 +95,7 @@ static int rk_aes_setkey(struct crypto_skcipher *cipher,
+           keylen != AES_KEYSIZE_256)
+               return -EINVAL;
+       ctx->keylen = keylen;
+-      memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen);
++      memcpy(ctx->key, key, keylen);
+       return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+@@ -111,7 +111,7 @@ static int rk_des_setkey(struct crypto_skcipher *cipher,
+               return err;
+       ctx->keylen = keylen;
+-      memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
++      memcpy(ctx->key, key, keylen);
+       return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+@@ -127,7 +127,8 @@ static int rk_tdes_setkey(struct crypto_skcipher *cipher,
+               return err;
+       ctx->keylen = keylen;
+-      memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
++      memcpy(ctx->key, key, keylen);
++
+       return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+@@ -283,6 +284,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
+                            RK_CRYPTO_TDES_BYTESWAP_IV;
+               CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
+               memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
++              memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen);
+               conf_reg = RK_CRYPTO_DESSEL;
+       } else {
+               rctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
+@@ -295,6 +297,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
+                       rctx->mode |= RK_CRYPTO_AES_256BIT_key;
+               CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode);
+               memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize);
++              memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen);
+       }
+       conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
+                   RK_CRYPTO_BYTESWAP_BRFIFO;
+@@ -484,6 +487,7 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
+ {
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      memzero_explicit(ctx->key, ctx->keylen);
+       free_page((unsigned long)ctx->dev->addr_vir);
+       crypto_free_skcipher(ctx->fallback_tfm);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-rockchip-delete-unneeded-variable-initializat.patch b/queue-5.10/crypto-rockchip-delete-unneeded-variable-initializat.patch
new file mode 100644 (file)
index 0000000..6fe5e9b
--- /dev/null
@@ -0,0 +1,35 @@
+From deee07f13535fee36ad22bb338e6365ae120258f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Apr 2021 11:01:39 +0800
+Subject: crypto: rockchip - delete unneeded variable initialization
+
+From: Kai Ye <yekai13@huawei.com>
+
+[ Upstream commit 3d8c5f5a08c39835a365c69d1a6d9518722ed19e ]
+
+Delete unneeded variable initialization
+
+Signed-off-by: Kai Ye <yekai13@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 57d67c6e8219 ("crypto: rockchip - rework by using crypto_engine")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/rockchip/rk3288_crypto_ahash.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+index f1d482ecc195..c762e462eb57 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+@@ -82,7 +82,7 @@ static void rk_ahash_reg_init(struct rk_crypto_info *dev)
+ {
+       struct ahash_request *req = ahash_request_cast(dev->async_req);
+       struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
+-      int reg_status = 0;
++      int reg_status;
+       reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL) |
+                    RK_CRYPTO_HASH_FLUSH | _SBF(0xffff, 16);
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-rockchip-do-not-do-custom-power-management.patch b/queue-5.10/crypto-rockchip-do-not-do-custom-power-management.patch
new file mode 100644 (file)
index 0000000..3092f69
--- /dev/null
@@ -0,0 +1,111 @@
+From e33b96eafa7e2703e6177ecb16cfd229e3a23443 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Sep 2022 07:54:41 +0000
+Subject: crypto: rockchip - do not do custom power management
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit c50ef1411c8cbad0c7db100c477126076b6e3348 ]
+
+The clock enable/disable at tfm init/exit is fragile,
+if 2 tfm are init in the same time and one is removed just after,
+it will leave the hardware uncloked even if a user remains.
+
+Instead simply enable clocks at probe time.
+We will do PM later.
+
+Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
+Reviewed-by: John Keeping <john@metanate.com>
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/rockchip/rk3288_crypto.c          | 4 ++--
+ drivers/crypto/rockchip/rk3288_crypto.h          | 2 --
+ drivers/crypto/rockchip/rk3288_crypto_ahash.c    | 3 +--
+ drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 5 +++--
+ 4 files changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
+index 35d73061d156..5f8444b9633a 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.c
++++ b/drivers/crypto/rockchip/rk3288_crypto.c
+@@ -395,8 +395,7 @@ static int rk_crypto_probe(struct platform_device *pdev)
+                    rk_crypto_done_task_cb, (unsigned long)crypto_info);
+       crypto_init_queue(&crypto_info->queue, 50);
+-      crypto_info->enable_clk = rk_crypto_enable_clk;
+-      crypto_info->disable_clk = rk_crypto_disable_clk;
++      rk_crypto_enable_clk(crypto_info);
+       crypto_info->load_data = rk_load_data;
+       crypto_info->unload_data = rk_unload_data;
+       crypto_info->enqueue = rk_crypto_enqueue;
+@@ -423,6 +422,7 @@ static int rk_crypto_remove(struct platform_device *pdev)
+       struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev);
+       rk_crypto_unregister();
++      rk_crypto_disable_clk(crypto_tmp);
+       tasklet_kill(&crypto_tmp->done_task);
+       tasklet_kill(&crypto_tmp->queue_task);
+       return 0;
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
+index 3db595570c9c..39ffcd630760 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.h
++++ b/drivers/crypto/rockchip/rk3288_crypto.h
+@@ -219,8 +219,6 @@ struct rk_crypto_info {
+       int (*start)(struct rk_crypto_info *dev);
+       int (*update)(struct rk_crypto_info *dev);
+       void (*complete)(struct crypto_async_request *base, int err);
+-      int (*enable_clk)(struct rk_crypto_info *dev);
+-      void (*disable_clk)(struct rk_crypto_info *dev);
+       int (*load_data)(struct rk_crypto_info *dev,
+                        struct scatterlist *sg_src,
+                        struct scatterlist *sg_dst);
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+index 81befe7febaa..9583310a69d5 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+@@ -301,7 +301,7 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
+                                sizeof(struct rk_ahash_rctx) +
+                                crypto_ahash_reqsize(tctx->fallback_tfm));
+-      return tctx->dev->enable_clk(tctx->dev);
++      return 0;
+ }
+ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
+@@ -309,7 +309,6 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
+       struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);
+       free_page((unsigned long)tctx->dev->addr_vir);
+-      return tctx->dev->disable_clk(tctx->dev);
+ }
+ struct rk_crypto_tmp rk_ahash_sha1 = {
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+index 5bbf0d2722e1..8c44a19eab75 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+@@ -388,8 +388,10 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
+       ctx->dev->update = rk_ablk_rx;
+       ctx->dev->complete = rk_crypto_complete;
+       ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL);
++      if (!ctx->dev->addr_vir)
++              return -ENOMEM;
+-      return ctx->dev->addr_vir ? ctx->dev->enable_clk(ctx->dev) : -ENOMEM;
++      return 0;
+ }
+ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
+@@ -397,7 +399,6 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       free_page((unsigned long)ctx->dev->addr_vir);
+-      ctx->dev->disable_clk(ctx->dev);
+ }
+ struct rk_crypto_tmp rk_ecb_aes_alg = {
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-rockchip-do-not-store-mode-globally.patch b/queue-5.10/crypto-rockchip-do-not-store-mode-globally.patch
new file mode 100644 (file)
index 0000000..ecc098c
--- /dev/null
@@ -0,0 +1,275 @@
+From cdad1c8273d3322acff158cdccd16b185e568db8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Sep 2022 07:54:43 +0000
+Subject: crypto: rockchip - do not store mode globally
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit 87e356c4966444866186f68f05832fdcc0f351a3 ]
+
+Storing the mode globally does not work if 2 requests are handled in the
+same time.
+We should store it in a request context.
+
+Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
+Reviewed-by: John Keeping <john@metanate.com>
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/rockchip/rk3288_crypto.h       |  5 +-
+ .../crypto/rockchip/rk3288_crypto_skcipher.c  | 58 ++++++++++++-------
+ 2 files changed, 41 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
+index 39ffcd630760..65b9b58bb304 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.h
++++ b/drivers/crypto/rockchip/rk3288_crypto.h
+@@ -244,10 +244,13 @@ struct rk_ahash_rctx {
+ struct rk_cipher_ctx {
+       struct rk_crypto_info           *dev;
+       unsigned int                    keylen;
+-      u32                             mode;
+       u8                              iv[AES_BLOCK_SIZE];
+ };
++struct rk_cipher_rctx {
++      u32                             mode;
++};
++
+ enum alg_type {
+       ALG_TYPE_HASH,
+       ALG_TYPE_CIPHER,
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+index 8c44a19eab75..bbd0bf52bf07 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+@@ -76,9 +76,10 @@ static int rk_aes_ecb_encrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = RK_CRYPTO_AES_ECB_MODE;
++      rctx->mode = RK_CRYPTO_AES_ECB_MODE;
+       return rk_handle_req(dev, req);
+ }
+@@ -86,9 +87,10 @@ static int rk_aes_ecb_decrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
++      rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
+       return rk_handle_req(dev, req);
+ }
+@@ -96,9 +98,10 @@ static int rk_aes_cbc_encrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = RK_CRYPTO_AES_CBC_MODE;
++      rctx->mode = RK_CRYPTO_AES_CBC_MODE;
+       return rk_handle_req(dev, req);
+ }
+@@ -106,9 +109,10 @@ static int rk_aes_cbc_decrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
++      rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
+       return rk_handle_req(dev, req);
+ }
+@@ -116,9 +120,10 @@ static int rk_des_ecb_encrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = 0;
++      rctx->mode = 0;
+       return rk_handle_req(dev, req);
+ }
+@@ -126,9 +131,10 @@ static int rk_des_ecb_decrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = RK_CRYPTO_DEC;
++      rctx->mode = RK_CRYPTO_DEC;
+       return rk_handle_req(dev, req);
+ }
+@@ -136,9 +142,10 @@ static int rk_des_cbc_encrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
++      rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
+       return rk_handle_req(dev, req);
+ }
+@@ -146,9 +153,10 @@ static int rk_des_cbc_decrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
++      rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
+       return rk_handle_req(dev, req);
+ }
+@@ -156,9 +164,10 @@ static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = RK_CRYPTO_TDES_SELECT;
++      rctx->mode = RK_CRYPTO_TDES_SELECT;
+       return rk_handle_req(dev, req);
+ }
+@@ -166,9 +175,10 @@ static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
++      rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
+       return rk_handle_req(dev, req);
+ }
+@@ -176,9 +186,10 @@ static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
++      rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
+       return rk_handle_req(dev, req);
+ }
+@@ -186,9 +197,10 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req)
+ {
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_crypto_info *dev = ctx->dev;
+-      ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
++      rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
+                   RK_CRYPTO_DEC;
+       return rk_handle_req(dev, req);
+ }
+@@ -199,6 +211,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
+               skcipher_request_cast(dev->async_req);
+       struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
+       struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
+       u32 ivsize, block, conf_reg = 0;
+@@ -206,22 +219,22 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
+       ivsize = crypto_skcipher_ivsize(cipher);
+       if (block == DES_BLOCK_SIZE) {
+-              ctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
++              rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
+                            RK_CRYPTO_TDES_BYTESWAP_KEY |
+                            RK_CRYPTO_TDES_BYTESWAP_IV;
+-              CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, ctx->mode);
++              CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
+               memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
+               conf_reg = RK_CRYPTO_DESSEL;
+       } else {
+-              ctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
++              rctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
+                            RK_CRYPTO_AES_KEY_CHANGE |
+                            RK_CRYPTO_AES_BYTESWAP_KEY |
+                            RK_CRYPTO_AES_BYTESWAP_IV;
+               if (ctx->keylen == AES_KEYSIZE_192)
+-                      ctx->mode |= RK_CRYPTO_AES_192BIT_key;
++                      rctx->mode |= RK_CRYPTO_AES_192BIT_key;
+               else if (ctx->keylen == AES_KEYSIZE_256)
+-                      ctx->mode |= RK_CRYPTO_AES_256BIT_key;
+-              CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, ctx->mode);
++                      rctx->mode |= RK_CRYPTO_AES_256BIT_key;
++              CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode);
+               memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize);
+       }
+       conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
+@@ -246,6 +259,7 @@ static int rk_set_data_start(struct rk_crypto_info *dev)
+       struct skcipher_request *req =
+               skcipher_request_cast(dev->async_req);
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       u32 ivsize = crypto_skcipher_ivsize(tfm);
+       u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
+@@ -254,7 +268,7 @@ static int rk_set_data_start(struct rk_crypto_info *dev)
+       /* Store the iv that need to be updated in chain mode.
+        * And update the IV buffer to contain the next IV for decryption mode.
+        */
+-      if (ctx->mode & RK_CRYPTO_DEC) {
++      if (rctx->mode & RK_CRYPTO_DEC) {
+               memcpy(ctx->iv, src_last_blk, ivsize);
+               sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv,
+                                  ivsize, dev->total - ivsize);
+@@ -294,11 +308,12 @@ static void rk_iv_copyback(struct rk_crypto_info *dev)
+       struct skcipher_request *req =
+               skcipher_request_cast(dev->async_req);
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       u32 ivsize = crypto_skcipher_ivsize(tfm);
+       /* Update the IV buffer to contain the next IV for encryption mode. */
+-      if (!(ctx->mode & RK_CRYPTO_DEC)) {
++      if (!(rctx->mode & RK_CRYPTO_DEC)) {
+               if (dev->aligned) {
+                       memcpy(req->iv, sg_virt(dev->sg_dst) +
+                               dev->sg_dst->length - ivsize, ivsize);
+@@ -314,11 +329,12 @@ static void rk_update_iv(struct rk_crypto_info *dev)
+       struct skcipher_request *req =
+               skcipher_request_cast(dev->async_req);
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       u32 ivsize = crypto_skcipher_ivsize(tfm);
+       u8 *new_iv = NULL;
+-      if (ctx->mode & RK_CRYPTO_DEC) {
++      if (rctx->mode & RK_CRYPTO_DEC) {
+               new_iv = ctx->iv;
+       } else {
+               new_iv = page_address(sg_page(dev->sg_dst)) +
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-rockchip-remove-non-aligned-handling.patch b/queue-5.10/crypto-rockchip-remove-non-aligned-handling.patch
new file mode 100644 (file)
index 0000000..94fcab1
--- /dev/null
@@ -0,0 +1,280 @@
+From 10b9bfdd6340f745f40afdaf2a82b141f49bfb3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Sep 2022 07:54:47 +0000
+Subject: crypto: rockchip - remove non-aligned handling
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit bb3c7b73363c9a149b12b74c44ae94b73a8fddf8 ]
+
+Now driver have fallback for un-aligned cases, remove all code handling
+those cases.
+
+Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
+Reviewed-by: John Keeping <john@metanate.com>
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/rockchip/rk3288_crypto.c       | 69 +++++--------------
+ drivers/crypto/rockchip/rk3288_crypto.h       |  4 --
+ drivers/crypto/rockchip/rk3288_crypto_ahash.c | 22 ++----
+ .../crypto/rockchip/rk3288_crypto_skcipher.c  | 39 +++--------
+ 4 files changed, 31 insertions(+), 103 deletions(-)
+
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
+index 5f8444b9633a..31453257ab11 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.c
++++ b/drivers/crypto/rockchip/rk3288_crypto.c
+@@ -88,63 +88,26 @@ static int rk_load_data(struct rk_crypto_info *dev,
+ {
+       unsigned int count;
+-      dev->aligned = dev->aligned ?
+-              check_alignment(sg_src, sg_dst, dev->align_size) :
+-              dev->aligned;
+-      if (dev->aligned) {
+-              count = min(dev->left_bytes, sg_src->length);
+-              dev->left_bytes -= count;
+-
+-              if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) {
+-                      dev_err(dev->dev, "[%s:%d] dma_map_sg(src)  error\n",
++      count = min(dev->left_bytes, sg_src->length);
++      dev->left_bytes -= count;
++
++      if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) {
++              dev_err(dev->dev, "[%s:%d] dma_map_sg(src)  error\n",
+                               __func__, __LINE__);
+-                      return -EINVAL;
+-              }
+-              dev->addr_in = sg_dma_address(sg_src);
++              return -EINVAL;
++      }
++      dev->addr_in = sg_dma_address(sg_src);
+-              if (sg_dst) {
+-                      if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) {
+-                              dev_err(dev->dev,
++      if (sg_dst) {
++              if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) {
++                      dev_err(dev->dev,
+                                       "[%s:%d] dma_map_sg(dst)  error\n",
+                                       __func__, __LINE__);
+-                              dma_unmap_sg(dev->dev, sg_src, 1,
+-                                           DMA_TO_DEVICE);
+-                              return -EINVAL;
+-                      }
+-                      dev->addr_out = sg_dma_address(sg_dst);
+-              }
+-      } else {
+-              count = (dev->left_bytes > PAGE_SIZE) ?
+-                      PAGE_SIZE : dev->left_bytes;
+-
+-              if (!sg_pcopy_to_buffer(dev->first, dev->src_nents,
+-                                      dev->addr_vir, count,
+-                                      dev->total - dev->left_bytes)) {
+-                      dev_err(dev->dev, "[%s:%d] pcopy err\n",
+-                              __func__, __LINE__);
++                      dma_unmap_sg(dev->dev, sg_src, 1,
++                                      DMA_TO_DEVICE);
+                       return -EINVAL;
+               }
+-              dev->left_bytes -= count;
+-              sg_init_one(&dev->sg_tmp, dev->addr_vir, count);
+-              if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1, DMA_TO_DEVICE)) {
+-                      dev_err(dev->dev, "[%s:%d] dma_map_sg(sg_tmp)  error\n",
+-                              __func__, __LINE__);
+-                      return -ENOMEM;
+-              }
+-              dev->addr_in = sg_dma_address(&dev->sg_tmp);
+-
+-              if (sg_dst) {
+-                      if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1,
+-                                      DMA_FROM_DEVICE)) {
+-                              dev_err(dev->dev,
+-                                      "[%s:%d] dma_map_sg(sg_tmp)  error\n",
+-                                      __func__, __LINE__);
+-                              dma_unmap_sg(dev->dev, &dev->sg_tmp, 1,
+-                                           DMA_TO_DEVICE);
+-                              return -ENOMEM;
+-                      }
+-                      dev->addr_out = sg_dma_address(&dev->sg_tmp);
+-              }
++              dev->addr_out = sg_dma_address(sg_dst);
+       }
+       dev->count = count;
+       return 0;
+@@ -154,11 +117,11 @@ static void rk_unload_data(struct rk_crypto_info *dev)
+ {
+       struct scatterlist *sg_in, *sg_out;
+-      sg_in = dev->aligned ? dev->sg_src : &dev->sg_tmp;
++      sg_in = dev->sg_src;
+       dma_unmap_sg(dev->dev, sg_in, 1, DMA_TO_DEVICE);
+       if (dev->sg_dst) {
+-              sg_out = dev->aligned ? dev->sg_dst : &dev->sg_tmp;
++              sg_out = dev->sg_dst;
+               dma_unmap_sg(dev->dev, sg_out, 1, DMA_FROM_DEVICE);
+       }
+ }
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
+index 1eabf3952a03..acaf6f875d0b 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.h
++++ b/drivers/crypto/rockchip/rk3288_crypto.h
+@@ -203,12 +203,8 @@ struct rk_crypto_info {
+       /* the public variable */
+       struct scatterlist              *sg_src;
+       struct scatterlist              *sg_dst;
+-      struct scatterlist              sg_tmp;
+       struct scatterlist              *first;
+       unsigned int                    left_bytes;
+-      void                            *addr_vir;
+-      int                             aligned;
+-      int                             align_size;
+       size_t                          src_nents;
+       size_t                          dst_nents;
+       unsigned int                    total;
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+index f917adc4a608..f1d482ecc195 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+@@ -236,8 +236,6 @@ static int rk_ahash_start(struct rk_crypto_info *dev)
+       dev->total = req->nbytes;
+       dev->left_bytes = req->nbytes;
+-      dev->aligned = 0;
+-      dev->align_size = 4;
+       dev->sg_dst = NULL;
+       dev->sg_src = req->src;
+       dev->first = req->src;
+@@ -272,15 +270,13 @@ static int rk_ahash_crypto_rx(struct rk_crypto_info *dev)
+       dev->unload_data(dev);
+       if (dev->left_bytes) {
+-              if (dev->aligned) {
+-                      if (sg_is_last(dev->sg_src)) {
+-                              dev_warn(dev->dev, "[%s:%d], Lack of data\n",
+-                                       __func__, __LINE__);
+-                              err = -ENOMEM;
+-                              goto out_rx;
+-                      }
+-                      dev->sg_src = sg_next(dev->sg_src);
++              if (sg_is_last(dev->sg_src)) {
++                      dev_warn(dev->dev, "[%s:%d], Lack of data\n",
++                                      __func__, __LINE__);
++                      err = -ENOMEM;
++                      goto out_rx;
+               }
++              dev->sg_src = sg_next(dev->sg_src);
+               err = rk_ahash_set_data_start(dev);
+       } else {
+               /*
+@@ -318,11 +314,6 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
+       algt = container_of(alg, struct rk_crypto_tmp, alg.hash);
+       tctx->dev = algt->dev;
+-      tctx->dev->addr_vir = (void *)__get_free_page(GFP_KERNEL);
+-      if (!tctx->dev->addr_vir) {
+-              dev_err(tctx->dev->dev, "failed to kmalloc for addr_vir\n");
+-              return -ENOMEM;
+-      }
+       tctx->dev->start = rk_ahash_start;
+       tctx->dev->update = rk_ahash_crypto_rx;
+       tctx->dev->complete = rk_ahash_crypto_complete;
+@@ -345,7 +336,6 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
+ {
+       struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);
+-      free_page((unsigned long)tctx->dev->addr_vir);
+       crypto_free_ahash(tctx->fallback_tfm);
+ }
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+index 1ef94f8db2c5..d067b7f09165 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+@@ -356,7 +356,6 @@ static int rk_ablk_start(struct rk_crypto_info *dev)
+       dev->src_nents = sg_nents(req->src);
+       dev->sg_dst = req->dst;
+       dev->dst_nents = sg_nents(req->dst);
+-      dev->aligned = 1;
+       spin_lock_irqsave(&dev->lock, flags);
+       rk_ablk_hw_init(dev);
+@@ -376,13 +375,9 @@ static void rk_iv_copyback(struct rk_crypto_info *dev)
+       /* Update the IV buffer to contain the next IV for encryption mode. */
+       if (!(rctx->mode & RK_CRYPTO_DEC)) {
+-              if (dev->aligned) {
+-                      memcpy(req->iv, sg_virt(dev->sg_dst) +
+-                              dev->sg_dst->length - ivsize, ivsize);
+-              } else {
+-                      memcpy(req->iv, dev->addr_vir +
+-                              dev->count - ivsize, ivsize);
+-              }
++              memcpy(req->iv,
++                     sg_virt(dev->sg_dst) + dev->sg_dst->length - ivsize,
++                     ivsize);
+       }
+ }
+@@ -420,27 +415,16 @@ static int rk_ablk_rx(struct rk_crypto_info *dev)
+               skcipher_request_cast(dev->async_req);
+       dev->unload_data(dev);
+-      if (!dev->aligned) {
+-              if (!sg_pcopy_from_buffer(req->dst, dev->dst_nents,
+-                                        dev->addr_vir, dev->count,
+-                                        dev->total - dev->left_bytes -
+-                                        dev->count)) {
+-                      err = -EINVAL;
+-                      goto out_rx;
+-              }
+-      }
+       if (dev->left_bytes) {
+               rk_update_iv(dev);
+-              if (dev->aligned) {
+-                      if (sg_is_last(dev->sg_src)) {
+-                              dev_err(dev->dev, "[%s:%d] Lack of data\n",
++              if (sg_is_last(dev->sg_src)) {
++                      dev_err(dev->dev, "[%s:%d] Lack of data\n",
+                                       __func__, __LINE__);
+-                              err = -ENOMEM;
+-                              goto out_rx;
+-                      }
+-                      dev->sg_src = sg_next(dev->sg_src);
+-                      dev->sg_dst = sg_next(dev->sg_dst);
++                      err = -ENOMEM;
++                      goto out_rx;
+               }
++              dev->sg_src = sg_next(dev->sg_src);
++              dev->sg_dst = sg_next(dev->sg_dst);
+               err = rk_set_data_start(dev);
+       } else {
+               rk_iv_copyback(dev);
+@@ -462,13 +446,9 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
+       algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
+       ctx->dev = algt->dev;
+-      ctx->dev->align_size = crypto_tfm_alg_alignmask(crypto_skcipher_tfm(tfm)) + 1;
+       ctx->dev->start = rk_ablk_start;
+       ctx->dev->update = rk_ablk_rx;
+       ctx->dev->complete = rk_crypto_complete;
+-      ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL);
+-      if (!ctx->dev->addr_vir)
+-              return -ENOMEM;
+       ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
+       if (IS_ERR(ctx->fallback_tfm)) {
+@@ -488,7 +468,6 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       memzero_explicit(ctx->key, ctx->keylen);
+-      free_page((unsigned long)ctx->dev->addr_vir);
+       crypto_free_skcipher(ctx->fallback_tfm);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-rockchip-rework-by-using-crypto_engine.patch b/queue-5.10/crypto-rockchip-rework-by-using-crypto_engine.patch
new file mode 100644 (file)
index 0000000..39e7c51
--- /dev/null
@@ -0,0 +1,902 @@
+From 5e2381b9f1b03b897b131b1e76e21d165a9d829f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Sep 2022 07:54:48 +0000
+Subject: crypto: rockchip - rework by using crypto_engine
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit 57d67c6e8219b2a034c16d6149e30fb40fd39935 ]
+
+Instead of doing manual queue management, let's use the crypto/engine
+for that.
+In the same time, rework the requests handling to be easier to
+understand (and fix all bugs related to them).
+
+Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
+Reviewed-by: John Keeping <john@metanate.com>
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/Kconfig                        |   1 +
+ drivers/crypto/rockchip/rk3288_crypto.c       | 152 +----------
+ drivers/crypto/rockchip/rk3288_crypto.h       |  39 +--
+ drivers/crypto/rockchip/rk3288_crypto_ahash.c | 144 +++++-----
+ .../crypto/rockchip/rk3288_crypto_skcipher.c  | 250 +++++++++---------
+ 5 files changed, 221 insertions(+), 365 deletions(-)
+
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
+index 8aa8b330df70..0a3dd0793f30 100644
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -754,6 +754,7 @@ config CRYPTO_DEV_ROCKCHIP
+       select CRYPTO_CBC
+       select CRYPTO_DES
+       select CRYPTO_AES
++      select CRYPTO_ENGINE
+       select CRYPTO_LIB_DES
+       select CRYPTO_MD5
+       select CRYPTO_SHA1
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
+index 31453257ab11..14a0aef18ab1 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.c
++++ b/drivers/crypto/rockchip/rk3288_crypto.c
+@@ -65,149 +65,24 @@ static void rk_crypto_disable_clk(struct rk_crypto_info *dev)
+       clk_disable_unprepare(dev->sclk);
+ }
+-static int check_alignment(struct scatterlist *sg_src,
+-                         struct scatterlist *sg_dst,
+-                         int align_mask)
+-{
+-      int in, out, align;
+-
+-      in = IS_ALIGNED((uint32_t)sg_src->offset, 4) &&
+-           IS_ALIGNED((uint32_t)sg_src->length, align_mask);
+-      if (!sg_dst)
+-              return in;
+-      out = IS_ALIGNED((uint32_t)sg_dst->offset, 4) &&
+-            IS_ALIGNED((uint32_t)sg_dst->length, align_mask);
+-      align = in && out;
+-
+-      return (align && (sg_src->length == sg_dst->length));
+-}
+-
+-static int rk_load_data(struct rk_crypto_info *dev,
+-                      struct scatterlist *sg_src,
+-                      struct scatterlist *sg_dst)
+-{
+-      unsigned int count;
+-
+-      count = min(dev->left_bytes, sg_src->length);
+-      dev->left_bytes -= count;
+-
+-      if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) {
+-              dev_err(dev->dev, "[%s:%d] dma_map_sg(src)  error\n",
+-                              __func__, __LINE__);
+-              return -EINVAL;
+-      }
+-      dev->addr_in = sg_dma_address(sg_src);
+-
+-      if (sg_dst) {
+-              if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) {
+-                      dev_err(dev->dev,
+-                                      "[%s:%d] dma_map_sg(dst)  error\n",
+-                                      __func__, __LINE__);
+-                      dma_unmap_sg(dev->dev, sg_src, 1,
+-                                      DMA_TO_DEVICE);
+-                      return -EINVAL;
+-              }
+-              dev->addr_out = sg_dma_address(sg_dst);
+-      }
+-      dev->count = count;
+-      return 0;
+-}
+-
+-static void rk_unload_data(struct rk_crypto_info *dev)
+-{
+-      struct scatterlist *sg_in, *sg_out;
+-
+-      sg_in = dev->sg_src;
+-      dma_unmap_sg(dev->dev, sg_in, 1, DMA_TO_DEVICE);
+-
+-      if (dev->sg_dst) {
+-              sg_out = dev->sg_dst;
+-              dma_unmap_sg(dev->dev, sg_out, 1, DMA_FROM_DEVICE);
+-      }
+-}
+-
+ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id)
+ {
+       struct rk_crypto_info *dev  = platform_get_drvdata(dev_id);
+       u32 interrupt_status;
+-      spin_lock(&dev->lock);
+       interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS);
+       CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status);
++      dev->status = 1;
+       if (interrupt_status & 0x0a) {
+               dev_warn(dev->dev, "DMA Error\n");
+-              dev->err = -EFAULT;
++              dev->status = 0;
+       }
+-      tasklet_schedule(&dev->done_task);
++      complete(&dev->complete);
+-      spin_unlock(&dev->lock);
+       return IRQ_HANDLED;
+ }
+-static int rk_crypto_enqueue(struct rk_crypto_info *dev,
+-                            struct crypto_async_request *async_req)
+-{
+-      unsigned long flags;
+-      int ret;
+-
+-      spin_lock_irqsave(&dev->lock, flags);
+-      ret = crypto_enqueue_request(&dev->queue, async_req);
+-      if (dev->busy) {
+-              spin_unlock_irqrestore(&dev->lock, flags);
+-              return ret;
+-      }
+-      dev->busy = true;
+-      spin_unlock_irqrestore(&dev->lock, flags);
+-      tasklet_schedule(&dev->queue_task);
+-
+-      return ret;
+-}
+-
+-static void rk_crypto_queue_task_cb(unsigned long data)
+-{
+-      struct rk_crypto_info *dev = (struct rk_crypto_info *)data;
+-      struct crypto_async_request *async_req, *backlog;
+-      unsigned long flags;
+-      int err = 0;
+-
+-      dev->err = 0;
+-      spin_lock_irqsave(&dev->lock, flags);
+-      backlog   = crypto_get_backlog(&dev->queue);
+-      async_req = crypto_dequeue_request(&dev->queue);
+-
+-      if (!async_req) {
+-              dev->busy = false;
+-              spin_unlock_irqrestore(&dev->lock, flags);
+-              return;
+-      }
+-      spin_unlock_irqrestore(&dev->lock, flags);
+-
+-      if (backlog) {
+-              backlog->complete(backlog, -EINPROGRESS);
+-              backlog = NULL;
+-      }
+-
+-      dev->async_req = async_req;
+-      err = dev->start(dev);
+-      if (err)
+-              dev->complete(dev->async_req, err);
+-}
+-
+-static void rk_crypto_done_task_cb(unsigned long data)
+-{
+-      struct rk_crypto_info *dev = (struct rk_crypto_info *)data;
+-
+-      if (dev->err) {
+-              dev->complete(dev->async_req, dev->err);
+-              return;
+-      }
+-
+-      dev->err = dev->update(dev);
+-      if (dev->err)
+-              dev->complete(dev->async_req, dev->err);
+-}
+-
+ static struct rk_crypto_tmp *rk_cipher_algs[] = {
+       &rk_ecb_aes_alg,
+       &rk_cbc_aes_alg,
+@@ -300,8 +175,6 @@ static int rk_crypto_probe(struct platform_device *pdev)
+       if (err)
+               goto err_crypto;
+-      spin_lock_init(&crypto_info->lock);
+-
+       crypto_info->reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(crypto_info->reg)) {
+               err = PTR_ERR(crypto_info->reg);
+@@ -352,17 +225,11 @@ static int rk_crypto_probe(struct platform_device *pdev)
+       crypto_info->dev = &pdev->dev;
+       platform_set_drvdata(pdev, crypto_info);
+-      tasklet_init(&crypto_info->queue_task,
+-                   rk_crypto_queue_task_cb, (unsigned long)crypto_info);
+-      tasklet_init(&crypto_info->done_task,
+-                   rk_crypto_done_task_cb, (unsigned long)crypto_info);
+-      crypto_init_queue(&crypto_info->queue, 50);
++      crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true);
++      crypto_engine_start(crypto_info->engine);
++      init_completion(&crypto_info->complete);
+       rk_crypto_enable_clk(crypto_info);
+-      crypto_info->load_data = rk_load_data;
+-      crypto_info->unload_data = rk_unload_data;
+-      crypto_info->enqueue = rk_crypto_enqueue;
+-      crypto_info->busy = false;
+       err = rk_crypto_register(crypto_info);
+       if (err) {
+@@ -374,9 +241,9 @@ static int rk_crypto_probe(struct platform_device *pdev)
+       return 0;
+ err_register_alg:
+-      tasklet_kill(&crypto_info->queue_task);
+-      tasklet_kill(&crypto_info->done_task);
++      crypto_engine_exit(crypto_info->engine);
+ err_crypto:
++      dev_err(dev, "Crypto Accelerator not successfully registered\n");
+       return err;
+ }
+@@ -386,8 +253,7 @@ static int rk_crypto_remove(struct platform_device *pdev)
+       rk_crypto_unregister();
+       rk_crypto_disable_clk(crypto_tmp);
+-      tasklet_kill(&crypto_tmp->done_task);
+-      tasklet_kill(&crypto_tmp->queue_task);
++      crypto_engine_exit(crypto_tmp->engine);
+       return 0;
+ }
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
+index acaf6f875d0b..6b1413c0359b 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.h
++++ b/drivers/crypto/rockchip/rk3288_crypto.h
+@@ -5,9 +5,11 @@
+ #include <crypto/aes.h>
+ #include <crypto/internal/des.h>
+ #include <crypto/algapi.h>
++#include <linux/dma-mapping.h>
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/scatterlist.h>
++#include <crypto/engine.h>
+ #include <crypto/internal/hash.h>
+ #include <crypto/internal/skcipher.h>
+@@ -192,39 +194,15 @@ struct rk_crypto_info {
+       struct reset_control            *rst;
+       void __iomem                    *reg;
+       int                             irq;
+-      struct crypto_queue             queue;
+-      struct tasklet_struct           queue_task;
+-      struct tasklet_struct           done_task;
+-      struct crypto_async_request     *async_req;
+-      int                             err;
+-      /* device lock */
+-      spinlock_t                      lock;
+-
+-      /* the public variable */
+-      struct scatterlist              *sg_src;
+-      struct scatterlist              *sg_dst;
+-      struct scatterlist              *first;
+-      unsigned int                    left_bytes;
+-      size_t                          src_nents;
+-      size_t                          dst_nents;
+-      unsigned int                    total;
+-      unsigned int                    count;
+-      dma_addr_t                      addr_in;
+-      dma_addr_t                      addr_out;
+-      bool                            busy;
+-      int (*start)(struct rk_crypto_info *dev);
+-      int (*update)(struct rk_crypto_info *dev);
+-      void (*complete)(struct crypto_async_request *base, int err);
+-      int (*load_data)(struct rk_crypto_info *dev,
+-                       struct scatterlist *sg_src,
+-                       struct scatterlist *sg_dst);
+-      void (*unload_data)(struct rk_crypto_info *dev);
+-      int (*enqueue)(struct rk_crypto_info *dev,
+-                     struct crypto_async_request *async_req);
++
++      struct crypto_engine *engine;
++      struct completion complete;
++      int status;
+ };
+ /* the private variable of hash */
+ struct rk_ahash_ctx {
++      struct crypto_engine_ctx enginectx;
+       struct rk_crypto_info           *dev;
+       /* for fallback */
+       struct crypto_ahash             *fallback_tfm;
+@@ -234,10 +212,12 @@ struct rk_ahash_ctx {
+ struct rk_ahash_rctx {
+       struct ahash_request            fallback_req;
+       u32                             mode;
++      int nrsg;
+ };
+ /* the private variable of cipher */
+ struct rk_cipher_ctx {
++      struct crypto_engine_ctx enginectx;
+       struct rk_crypto_info           *dev;
+       unsigned int                    keylen;
+       u8                              key[AES_MAX_KEY_SIZE];
+@@ -246,6 +226,7 @@ struct rk_cipher_ctx {
+ };
+ struct rk_cipher_rctx {
++      u8 backup_iv[AES_BLOCK_SIZE];
+       u32                             mode;
+       struct skcipher_request fallback_req;   // keep at the end
+ };
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+index c762e462eb57..edd40e16a3f0 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+@@ -9,6 +9,7 @@
+  * Some ideas are from marvell/cesa.c and s5p-sss.c driver.
+  */
+ #include <linux/device.h>
++#include <asm/unaligned.h>
+ #include "rk3288_crypto.h"
+ /*
+@@ -72,16 +73,12 @@ static int zero_message_process(struct ahash_request *req)
+       return 0;
+ }
+-static void rk_ahash_crypto_complete(struct crypto_async_request *base, int err)
++static void rk_ahash_reg_init(struct ahash_request *req)
+ {
+-      if (base->complete)
+-              base->complete(base, err);
+-}
+-
+-static void rk_ahash_reg_init(struct rk_crypto_info *dev)
+-{
+-      struct ahash_request *req = ahash_request_cast(dev->async_req);
+       struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
++      struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
++      struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
++      struct rk_crypto_info *dev = tctx->dev;
+       int reg_status;
+       reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL) |
+@@ -108,7 +105,7 @@ static void rk_ahash_reg_init(struct rk_crypto_info *dev)
+                                         RK_CRYPTO_BYTESWAP_BRFIFO |
+                                         RK_CRYPTO_BYTESWAP_BTFIFO);
+-      CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, dev->total);
++      CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, req->nbytes);
+ }
+ static int rk_ahash_init(struct ahash_request *req)
+@@ -206,44 +203,59 @@ static int rk_ahash_digest(struct ahash_request *req)
+       if (!req->nbytes)
+               return zero_message_process(req);
+-      else
+-              return dev->enqueue(dev, &req->base);
++
++      return crypto_transfer_hash_request_to_engine(dev->engine, req);
+ }
+-static void crypto_ahash_dma_start(struct rk_crypto_info *dev)
++static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlist *sg)
+ {
+-      CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, dev->addr_in);
+-      CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, (dev->count + 3) / 4);
++      CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, sg_dma_address(sg));
++      CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, sg_dma_len(sg) / 4);
+       CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_HASH_START |
+                                         (RK_CRYPTO_HASH_START << 16));
+ }
+-static int rk_ahash_set_data_start(struct rk_crypto_info *dev)
++static int rk_hash_prepare(struct crypto_engine *engine, void *breq)
++{
++      struct ahash_request *areq = container_of(breq, struct ahash_request, base);
++      struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++      struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++      struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
++      int ret;
++
++      ret = dma_map_sg(tctx->dev->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
++      if (ret <= 0)
++              return -EINVAL;
++
++      rctx->nrsg = ret;
++
++      return 0;
++}
++
++static int rk_hash_unprepare(struct crypto_engine *engine, void *breq)
+ {
+-      int err;
++      struct ahash_request *areq = container_of(breq, struct ahash_request, base);
++      struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++      struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++      struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
+-      err = dev->load_data(dev, dev->sg_src, NULL);
+-      if (!err)
+-              crypto_ahash_dma_start(dev);
+-      return err;
++      dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE);
++      return 0;
+ }
+-static int rk_ahash_start(struct rk_crypto_info *dev)
++static int rk_hash_run(struct crypto_engine *engine, void *breq)
+ {
+-      struct ahash_request *req = ahash_request_cast(dev->async_req);
+-      struct crypto_ahash *tfm;
+-      struct rk_ahash_rctx *rctx;
+-
+-      dev->total = req->nbytes;
+-      dev->left_bytes = req->nbytes;
+-      dev->sg_dst = NULL;
+-      dev->sg_src = req->src;
+-      dev->first = req->src;
+-      dev->src_nents = sg_nents(req->src);
+-      rctx = ahash_request_ctx(req);
++      struct ahash_request *areq = container_of(breq, struct ahash_request, base);
++      struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++      struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++      struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
++      struct scatterlist *sg = areq->src;
++      int err = 0;
++      int i;
++      u32 v;
++
+       rctx->mode = 0;
+-      tfm = crypto_ahash_reqtfm(req);
+       switch (crypto_ahash_digestsize(tfm)) {
+       case SHA1_DIGEST_SIZE:
+               rctx->mode = RK_CRYPTO_HASH_SHA1;
+@@ -255,30 +267,26 @@ static int rk_ahash_start(struct rk_crypto_info *dev)
+               rctx->mode = RK_CRYPTO_HASH_MD5;
+               break;
+       default:
+-              return -EINVAL;
++              err =  -EINVAL;
++              goto theend;
+       }
+-      rk_ahash_reg_init(dev);
+-      return rk_ahash_set_data_start(dev);
+-}
++      rk_ahash_reg_init(areq);
+-static int rk_ahash_crypto_rx(struct rk_crypto_info *dev)
+-{
+-      int err = 0;
+-      struct ahash_request *req = ahash_request_cast(dev->async_req);
+-      struct crypto_ahash *tfm;
+-
+-      dev->unload_data(dev);
+-      if (dev->left_bytes) {
+-              if (sg_is_last(dev->sg_src)) {
+-                      dev_warn(dev->dev, "[%s:%d], Lack of data\n",
+-                                      __func__, __LINE__);
+-                      err = -ENOMEM;
+-                      goto out_rx;
++      while (sg) {
++              reinit_completion(&tctx->dev->complete);
++              tctx->dev->status = 0;
++              crypto_ahash_dma_start(tctx->dev, sg);
++              wait_for_completion_interruptible_timeout(&tctx->dev->complete,
++                                                        msecs_to_jiffies(2000));
++              if (!tctx->dev->status) {
++                      dev_err(tctx->dev->dev, "DMA timeout\n");
++                      err = -EFAULT;
++                      goto theend;
+               }
+-              dev->sg_src = sg_next(dev->sg_src);
+-              err = rk_ahash_set_data_start(dev);
+-      } else {
++              sg = sg_next(sg);
++      }
++
+               /*
+                * it will take some time to process date after last dma
+                * transmission.
+@@ -289,18 +297,20 @@ static int rk_ahash_crypto_rx(struct rk_crypto_info *dev)
+                * efficiency, and make it response quickly when dma
+                * complete.
+                */
+-              while (!CRYPTO_READ(dev, RK_CRYPTO_HASH_STS))
+-                      udelay(10);
+-
+-              tfm = crypto_ahash_reqtfm(req);
+-              memcpy_fromio(req->result, dev->reg + RK_CRYPTO_HASH_DOUT_0,
+-                            crypto_ahash_digestsize(tfm));
+-              dev->complete(dev->async_req, 0);
+-              tasklet_schedule(&dev->queue_task);
++      while (!CRYPTO_READ(tctx->dev, RK_CRYPTO_HASH_STS))
++              udelay(10);
++
++      for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) {
++              v = readl(tctx->dev->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4);
++              put_unaligned_le32(v, areq->result + i * 4);
+       }
+-out_rx:
+-      return err;
++theend:
++      local_bh_disable();
++      crypto_finalize_hash_request(engine, breq, err);
++      local_bh_enable();
++
++      return 0;
+ }
+ static int rk_cra_hash_init(struct crypto_tfm *tfm)
+@@ -314,9 +324,6 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
+       algt = container_of(alg, struct rk_crypto_tmp, alg.hash);
+       tctx->dev = algt->dev;
+-      tctx->dev->start = rk_ahash_start;
+-      tctx->dev->update = rk_ahash_crypto_rx;
+-      tctx->dev->complete = rk_ahash_crypto_complete;
+       /* for fallback */
+       tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0,
+@@ -325,10 +332,15 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
+               dev_err(tctx->dev->dev, "Could not load fallback driver.\n");
+               return PTR_ERR(tctx->fallback_tfm);
+       }
++
+       crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
+                                sizeof(struct rk_ahash_rctx) +
+                                crypto_ahash_reqsize(tctx->fallback_tfm));
++      tctx->enginectx.op.do_one_request = rk_hash_run;
++      tctx->enginectx.op.prepare_request = rk_hash_prepare;
++      tctx->enginectx.op.unprepare_request = rk_hash_unprepare;
++
+       return 0;
+ }
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+index d067b7f09165..67a7e05d5ae3 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+@@ -9,6 +9,7 @@
+  * Some ideas are from marvell-cesa.c and s5p-sss.c driver.
+  */
+ #include <linux/device.h>
++#include <crypto/scatterwalk.h>
+ #include "rk3288_crypto.h"
+ #define RK_CRYPTO_DEC                 BIT(0)
+@@ -70,19 +71,15 @@ static int rk_cipher_fallback(struct skcipher_request *areq)
+       return err;
+ }
+-static void rk_crypto_complete(struct crypto_async_request *base, int err)
+-{
+-      if (base->complete)
+-              base->complete(base, err);
+-}
+-
+ static int rk_handle_req(struct rk_crypto_info *dev,
+                        struct skcipher_request *req)
+ {
++      struct crypto_engine *engine = dev->engine;
++
+       if (rk_cipher_need_fallback(req))
+               return rk_cipher_fallback(req);
+-      return dev->enqueue(dev, &req->base);
++      return crypto_transfer_skcipher_request_to_engine(engine, req);
+ }
+ static int rk_aes_setkey(struct crypto_skcipher *cipher,
+@@ -265,25 +262,21 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req)
+       return rk_handle_req(dev, req);
+ }
+-static void rk_ablk_hw_init(struct rk_crypto_info *dev)
++static void rk_ablk_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req)
+ {
+-      struct skcipher_request *req =
+-              skcipher_request_cast(dev->async_req);
+       struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
+       struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
+-      u32 ivsize, block, conf_reg = 0;
++      u32 block, conf_reg = 0;
+       block = crypto_tfm_alg_blocksize(tfm);
+-      ivsize = crypto_skcipher_ivsize(cipher);
+       if (block == DES_BLOCK_SIZE) {
+               rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
+                            RK_CRYPTO_TDES_BYTESWAP_KEY |
+                            RK_CRYPTO_TDES_BYTESWAP_IV;
+               CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
+-              memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
+               memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen);
+               conf_reg = RK_CRYPTO_DESSEL;
+       } else {
+@@ -296,7 +289,6 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
+               else if (ctx->keylen == AES_KEYSIZE_256)
+                       rctx->mode |= RK_CRYPTO_AES_256BIT_key;
+               CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode);
+-              memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize);
+               memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen);
+       }
+       conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
+@@ -306,133 +298,138 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
+                    RK_CRYPTO_BCDMA_ERR_ENA | RK_CRYPTO_BCDMA_DONE_ENA);
+ }
+-static void crypto_dma_start(struct rk_crypto_info *dev)
++static void crypto_dma_start(struct rk_crypto_info *dev,
++                           struct scatterlist *sgs,
++                           struct scatterlist *sgd, unsigned int todo)
+ {
+-      CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, dev->addr_in);
+-      CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, dev->count / 4);
+-      CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, dev->addr_out);
++      CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, sg_dma_address(sgs));
++      CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, todo);
++      CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, sg_dma_address(sgd));
+       CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_BLOCK_START |
+                    _SBF(RK_CRYPTO_BLOCK_START, 16));
+ }
+-static int rk_set_data_start(struct rk_crypto_info *dev)
++static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
+ {
+-      int err;
+-      struct skcipher_request *req =
+-              skcipher_request_cast(dev->async_req);
+-      struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+-      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
++      struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base);
++      struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+       struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+-      u32 ivsize = crypto_skcipher_ivsize(tfm);
+-      u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
+-              dev->sg_src->offset + dev->sg_src->length - ivsize;
+-
+-      /* Store the iv that need to be updated in chain mode.
+-       * And update the IV buffer to contain the next IV for decryption mode.
+-       */
+-      if (rctx->mode & RK_CRYPTO_DEC) {
+-              memcpy(ctx->iv, src_last_blk, ivsize);
+-              sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv,
+-                                 ivsize, dev->total - ivsize);
+-      }
+-
+-      err = dev->load_data(dev, dev->sg_src, dev->sg_dst);
+-      if (!err)
+-              crypto_dma_start(dev);
+-      return err;
+-}
+-
+-static int rk_ablk_start(struct rk_crypto_info *dev)
+-{
+-      struct skcipher_request *req =
+-              skcipher_request_cast(dev->async_req);
+-      unsigned long flags;
++      struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq);
++      struct scatterlist *sgs, *sgd;
+       int err = 0;
++      int ivsize = crypto_skcipher_ivsize(tfm);
++      int offset;
++      u8 iv[AES_BLOCK_SIZE];
++      u8 biv[AES_BLOCK_SIZE];
++      u8 *ivtouse = areq->iv;
++      unsigned int len = areq->cryptlen;
++      unsigned int todo;
++
++      ivsize = crypto_skcipher_ivsize(tfm);
++      if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) {
++              if (rctx->mode & RK_CRYPTO_DEC) {
++                      offset = areq->cryptlen - ivsize;
++                      scatterwalk_map_and_copy(rctx->backup_iv, areq->src,
++                                               offset, ivsize, 0);
++              }
++      }
+-      dev->left_bytes = req->cryptlen;
+-      dev->total = req->cryptlen;
+-      dev->sg_src = req->src;
+-      dev->first = req->src;
+-      dev->src_nents = sg_nents(req->src);
+-      dev->sg_dst = req->dst;
+-      dev->dst_nents = sg_nents(req->dst);
+-
+-      spin_lock_irqsave(&dev->lock, flags);
+-      rk_ablk_hw_init(dev);
+-      err = rk_set_data_start(dev);
+-      spin_unlock_irqrestore(&dev->lock, flags);
+-      return err;
+-}
+-
+-static void rk_iv_copyback(struct rk_crypto_info *dev)
+-{
+-      struct skcipher_request *req =
+-              skcipher_request_cast(dev->async_req);
+-      struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+-      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+-      struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+-      u32 ivsize = crypto_skcipher_ivsize(tfm);
++      sgs = areq->src;
++      sgd = areq->dst;
+-      /* Update the IV buffer to contain the next IV for encryption mode. */
+-      if (!(rctx->mode & RK_CRYPTO_DEC)) {
+-              memcpy(req->iv,
+-                     sg_virt(dev->sg_dst) + dev->sg_dst->length - ivsize,
+-                     ivsize);
++      while (sgs && sgd && len) {
++              if (!sgs->length) {
++                      sgs = sg_next(sgs);
++                      sgd = sg_next(sgd);
++                      continue;
++              }
++              if (rctx->mode & RK_CRYPTO_DEC) {
++                      /* we backup last block of source to be used as IV at next step */
++                      offset = sgs->length - ivsize;
++                      scatterwalk_map_and_copy(biv, sgs, offset, ivsize, 0);
++              }
++              if (sgs == sgd) {
++                      err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
++                      if (err <= 0) {
++                              err = -EINVAL;
++                              goto theend_iv;
++                      }
++              } else {
++                      err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
++                      if (err <= 0) {
++                              err = -EINVAL;
++                              goto theend_iv;
++                      }
++                      err = dma_map_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
++                      if (err <= 0) {
++                              err = -EINVAL;
++                              goto theend_sgs;
++                      }
++              }
++              err = 0;
++              rk_ablk_hw_init(ctx->dev, areq);
++              if (ivsize) {
++                      if (ivsize == DES_BLOCK_SIZE)
++                              memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize);
++                      else
++                              memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize);
++              }
++              reinit_completion(&ctx->dev->complete);
++              ctx->dev->status = 0;
++
++              todo = min(sg_dma_len(sgs), len);
++              len -= todo;
++              crypto_dma_start(ctx->dev, sgs, sgd, todo / 4);
++              wait_for_completion_interruptible_timeout(&ctx->dev->complete,
++                                                        msecs_to_jiffies(2000));
++              if (!ctx->dev->status) {
++                      dev_err(ctx->dev->dev, "DMA timeout\n");
++                      err = -EFAULT;
++                      goto theend;
++              }
++              if (sgs == sgd) {
++                      dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
++              } else {
++                      dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
++                      dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
++              }
++              if (rctx->mode & RK_CRYPTO_DEC) {
++                      memcpy(iv, biv, ivsize);
++                      ivtouse = iv;
++              } else {
++                      offset = sgd->length - ivsize;
++                      scatterwalk_map_and_copy(iv, sgd, offset, ivsize, 0);
++                      ivtouse = iv;
++              }
++              sgs = sg_next(sgs);
++              sgd = sg_next(sgd);
+       }
+-}
+-
+-static void rk_update_iv(struct rk_crypto_info *dev)
+-{
+-      struct skcipher_request *req =
+-              skcipher_request_cast(dev->async_req);
+-      struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+-      struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+-      struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+-      u32 ivsize = crypto_skcipher_ivsize(tfm);
+-      u8 *new_iv = NULL;
+-      if (rctx->mode & RK_CRYPTO_DEC) {
+-              new_iv = ctx->iv;
+-      } else {
+-              new_iv = page_address(sg_page(dev->sg_dst)) +
+-                       dev->sg_dst->offset + dev->sg_dst->length - ivsize;
++      if (areq->iv && ivsize > 0) {
++              offset = areq->cryptlen - ivsize;
++              if (rctx->mode & RK_CRYPTO_DEC) {
++                      memcpy(areq->iv, rctx->backup_iv, ivsize);
++                      memzero_explicit(rctx->backup_iv, ivsize);
++              } else {
++                      scatterwalk_map_and_copy(areq->iv, areq->dst, offset,
++                                               ivsize, 0);
++              }
+       }
+-      if (ivsize == DES_BLOCK_SIZE)
+-              memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, new_iv, ivsize);
+-      else if (ivsize == AES_BLOCK_SIZE)
+-              memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, new_iv, ivsize);
+-}
++theend:
++      local_bh_disable();
++      crypto_finalize_skcipher_request(engine, areq, err);
++      local_bh_enable();
++      return 0;
+-/* return:
+- *    true    some err was occurred
+- *    fault   no err, continue
+- */
+-static int rk_ablk_rx(struct rk_crypto_info *dev)
+-{
+-      int err = 0;
+-      struct skcipher_request *req =
+-              skcipher_request_cast(dev->async_req);
+-
+-      dev->unload_data(dev);
+-      if (dev->left_bytes) {
+-              rk_update_iv(dev);
+-              if (sg_is_last(dev->sg_src)) {
+-                      dev_err(dev->dev, "[%s:%d] Lack of data\n",
+-                                      __func__, __LINE__);
+-                      err = -ENOMEM;
+-                      goto out_rx;
+-              }
+-              dev->sg_src = sg_next(dev->sg_src);
+-              dev->sg_dst = sg_next(dev->sg_dst);
+-              err = rk_set_data_start(dev);
++theend_sgs:
++      if (sgs == sgd) {
++              dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
+       } else {
+-              rk_iv_copyback(dev);
+-              /* here show the calculation is over without any err */
+-              dev->complete(dev->async_req, 0);
+-              tasklet_schedule(&dev->queue_task);
++              dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
++              dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
+       }
+-out_rx:
++theend_iv:
+       return err;
+ }
+@@ -446,9 +443,6 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
+       algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
+       ctx->dev = algt->dev;
+-      ctx->dev->start = rk_ablk_start;
+-      ctx->dev->update = rk_ablk_rx;
+-      ctx->dev->complete = rk_crypto_complete;
+       ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
+       if (IS_ERR(ctx->fallback_tfm)) {
+@@ -460,6 +454,8 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
+       tfm->reqsize = sizeof(struct rk_cipher_rctx) +
+               crypto_skcipher_reqsize(ctx->fallback_tfm);
++      ctx->enginectx.op.do_one_request = rk_cipher_run;
++
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-sun8i-ss-use-dma_addr-instead-u32.patch b/queue-5.10/crypto-sun8i-ss-use-dma_addr-instead-u32.patch
new file mode 100644 (file)
index 0000000..9c1bd8e
--- /dev/null
@@ -0,0 +1,36 @@
+From ecbec850c335f2712740991eb5fc35dea4d5eb3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Sep 2022 08:55:55 +0000
+Subject: crypto: sun8i-ss - use dma_addr instead u32
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit 839b8ae2fc10f205317bcc32c9de18456756e1f5 ]
+
+The DMA address need to be stored in a dma_addr_t
+
+Fixes: 359e893e8af4 ("crypto: sun8i-ss - rework handling of IV")
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+index d0954993e2e3..49c7a8b464dd 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+@@ -105,7 +105,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq)
+       unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+       struct sun8i_ss_flow *sf = &ss->flows[rctx->flow];
+       int i = 0;
+-      u32 a;
++      dma_addr_t a;
+       int err;
+       rctx->ivlen = ivsize;
+-- 
+2.35.1
+
diff --git a/queue-5.10/crypto-tcrypt-fix-multibuffer-skcipher-speed-test-me.patch b/queue-5.10/crypto-tcrypt-fix-multibuffer-skcipher-speed-test-me.patch
new file mode 100644 (file)
index 0000000..7006690
--- /dev/null
@@ -0,0 +1,45 @@
+From 4d3e0a60633f330340e6f2040ec0392c77f6efb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 17:24:11 +0800
+Subject: crypto: tcrypt - Fix multibuffer skcipher speed test mem leak
+
+From: Zhang Yiqun <zhangyiqun@phytium.com.cn>
+
+[ Upstream commit 1aa33fc8d4032227253ceb736f47c52b859d9683 ]
+
+In the past, the data for mb-skcipher test has been allocated
+twice, that means the first allcated memory area is without
+free, which may cause a potential memory leakage. So this
+patch is to remove one allocation to fix this error.
+
+Fixes: e161c5930c15 ("crypto: tcrypt - add multibuf skcipher...")
+Signed-off-by: Zhang Yiqun <zhangyiqun@phytium.com.cn>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/tcrypt.c | 9 ---------
+ 1 file changed, 9 deletions(-)
+
+diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
+index 8609174e036e..7972d2784b3b 100644
+--- a/crypto/tcrypt.c
++++ b/crypto/tcrypt.c
+@@ -1282,15 +1282,6 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs,
+                       goto out_free_tfm;
+               }
+-
+-      for (i = 0; i < num_mb; ++i)
+-              if (testmgr_alloc_buf(data[i].xbuf)) {
+-                      while (i--)
+-                              testmgr_free_buf(data[i].xbuf);
+-                      goto out_free_tfm;
+-              }
+-
+-
+       for (i = 0; i < num_mb; ++i) {
+               data[i].req = skcipher_request_alloc(tfm, GFP_KERNEL);
+               if (!data[i].req) {
+-- 
+2.35.1
+
diff --git a/queue-5.10/cxl-fix-possible-null-ptr-deref-in-cxl_guest_init_af.patch b/queue-5.10/cxl-fix-possible-null-ptr-deref-in-cxl_guest_init_af.patch
new file mode 100644 (file)
index 0000000..af152ec
--- /dev/null
@@ -0,0 +1,99 @@
+From 6b7b1768a18491438dd1b482f86a8085eb4cca24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 22:54:39 +0800
+Subject: cxl: fix possible null-ptr-deref in cxl_guest_init_afu|adapter()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 61c80d1c3833e196256fb060382db94f24d3d9a7 ]
+
+If device_register() fails in cxl_register_afu|adapter(), the device
+is not added, device_unregister() can not be called in the error path,
+otherwise it will cause a null-ptr-deref because of removing not added
+device.
+
+As comment of device_register() says, it should use put_device() to give
+up the reference in the error path. So split device_unregister() into
+device_del() and put_device(), then goes to put dev when register fails.
+
+Fixes: 14baf4d9c739 ("cxl: Add guest-specific code")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: Andrew Donnellan <ajd@linux.ibm.com>
+Acked-by: Frederic Barrat <fbarrat@linux.ibm.com>
+Link: https://lore.kernel.org/r/20221111145440.2426970-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/cxl/guest.c | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
+index 186308f1f8eb..6334376826a9 100644
+--- a/drivers/misc/cxl/guest.c
++++ b/drivers/misc/cxl/guest.c
+@@ -959,10 +959,10 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n
+        * if it returns an error!
+        */
+       if ((rc = cxl_register_afu(afu)))
+-              goto err_put1;
++              goto err_put_dev;
+       if ((rc = cxl_sysfs_afu_add(afu)))
+-              goto err_put1;
++              goto err_del_dev;
+       /*
+        * pHyp doesn't expose the programming models supported by the
+@@ -978,7 +978,7 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n
+               afu->modes_supported = CXL_MODE_DIRECTED;
+       if ((rc = cxl_afu_select_best_mode(afu)))
+-              goto err_put2;
++              goto err_remove_sysfs;
+       adapter->afu[afu->slice] = afu;
+@@ -998,10 +998,12 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n
+       return 0;
+-err_put2:
++err_remove_sysfs:
+       cxl_sysfs_afu_remove(afu);
+-err_put1:
+-      device_unregister(&afu->dev);
++err_del_dev:
++      device_del(&afu->dev);
++err_put_dev:
++      put_device(&afu->dev);
+       free = false;
+       guest_release_serr_irq(afu);
+ err2:
+@@ -1135,18 +1137,20 @@ struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_devic
+        * even if it returns an error!
+        */
+       if ((rc = cxl_register_adapter(adapter)))
+-              goto err_put1;
++              goto err_put_dev;
+       if ((rc = cxl_sysfs_adapter_add(adapter)))
+-              goto err_put1;
++              goto err_del_dev;
+       /* release the context lock as the adapter is configured */
+       cxl_adapter_context_unlock(adapter);
+       return adapter;
+-err_put1:
+-      device_unregister(&adapter->dev);
++err_del_dev:
++      device_del(&adapter->dev);
++err_put_dev:
++      put_device(&adapter->dev);
+       free = false;
+       cxl_guest_remove_chardev(adapter);
+ err1:
+-- 
+2.35.1
+
diff --git a/queue-5.10/cxl-fix-possible-null-ptr-deref-in-cxl_pci_init_afu-.patch b/queue-5.10/cxl-fix-possible-null-ptr-deref-in-cxl_pci_init_afu-.patch
new file mode 100644 (file)
index 0000000..c89517c
--- /dev/null
@@ -0,0 +1,94 @@
+From 7728530601c6d4d963cd6be837ecbb64e2df0a28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 22:54:40 +0800
+Subject: cxl: fix possible null-ptr-deref in cxl_pci_init_afu|adapter()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 02cd3032b154fa02fdf90e7467abaeed889330b2 ]
+
+If device_register() fails in cxl_pci_afu|adapter(), the device
+is not added, device_unregister() can not be called in the error
+path, otherwise it will cause a null-ptr-deref because of removing
+not added device.
+
+As comment of device_register() says, it should use put_device() to give
+up the reference in the error path. So split device_unregister() into
+device_del() and put_device(), then goes to put dev when register fails.
+
+Fixes: f204e0b8cedd ("cxl: Driver code for powernv PCIe based cards for userspace access")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: Frederic Barrat <fbarrat@linux.ibm.com>
+Acked-by: Andrew Donnellan <ajd@linux.ibm.com>
+Link: https://lore.kernel.org/r/20221111145440.2426970-2-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/cxl/pci.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
+index 2ba899f5659f..0ac3f4cb88ac 100644
+--- a/drivers/misc/cxl/pci.c
++++ b/drivers/misc/cxl/pci.c
+@@ -1164,10 +1164,10 @@ static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
+        * if it returns an error!
+        */
+       if ((rc = cxl_register_afu(afu)))
+-              goto err_put1;
++              goto err_put_dev;
+       if ((rc = cxl_sysfs_afu_add(afu)))
+-              goto err_put1;
++              goto err_del_dev;
+       adapter->afu[afu->slice] = afu;
+@@ -1176,10 +1176,12 @@ static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
+       return 0;
+-err_put1:
++err_del_dev:
++      device_del(&afu->dev);
++err_put_dev:
+       pci_deconfigure_afu(afu);
+       cxl_debugfs_afu_remove(afu);
+-      device_unregister(&afu->dev);
++      put_device(&afu->dev);
+       return rc;
+ err_free_native:
+@@ -1667,23 +1669,25 @@ static struct cxl *cxl_pci_init_adapter(struct pci_dev *dev)
+        * even if it returns an error!
+        */
+       if ((rc = cxl_register_adapter(adapter)))
+-              goto err_put1;
++              goto err_put_dev;
+       if ((rc = cxl_sysfs_adapter_add(adapter)))
+-              goto err_put1;
++              goto err_del_dev;
+       /* Release the context lock as adapter is configured */
+       cxl_adapter_context_unlock(adapter);
+       return adapter;
+-err_put1:
++err_del_dev:
++      device_del(&adapter->dev);
++err_put_dev:
+       /* This should mirror cxl_remove_adapter, except without the
+        * sysfs parts
+        */
+       cxl_debugfs_adapter_remove(adapter);
+       cxl_deconfigure_adapter(adapter);
+-      device_unregister(&adapter->dev);
++      put_device(&adapter->dev);
+       return ERR_PTR(rc);
+ err_release:
+-- 
+2.35.1
+
diff --git a/queue-5.10/cxl-fix-refcount-leak-in-cxl_calc_capp_routing.patch b/queue-5.10/cxl-fix-refcount-leak-in-cxl_calc_capp_routing.patch
new file mode 100644 (file)
index 0000000..3d256c1
--- /dev/null
@@ -0,0 +1,41 @@
+From d1f4c706c75ce4e1bab73394427d10a64370df70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 10:00:38 +0400
+Subject: cxl: Fix refcount leak in cxl_calc_capp_routing
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 1d09697ff22908ae487fc8c4fbde1811732be523 ]
+
+of_get_next_parent() returns a node pointer with refcount incremented,
+we should use of_node_put() on it when not need anymore.
+This function only calls of_node_put() in normal path,
+missing it in the error path.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: f24be42aab37 ("cxl: Add psl9 specific code")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Acked-by: Andrew Donnellan <ajd@linux.ibm.com>
+Acked-by: Frederic Barrat <fbarrat@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220605060038.62217-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/cxl/pci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
+index 0ac3f4cb88ac..d183836d80e3 100644
+--- a/drivers/misc/cxl/pci.c
++++ b/drivers/misc/cxl/pci.c
+@@ -387,6 +387,7 @@ int cxl_calc_capp_routing(struct pci_dev *dev, u64 *chipid,
+       rc = get_phb_index(np, phb_index);
+       if (rc) {
+               pr_err("cxl: invalid phb index\n");
++              of_node_put(np);
+               return rc;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/debugfs-fix-error-when-writing-negative-value-to-ato.patch b/queue-5.10/debugfs-fix-error-when-writing-negative-value-to-ato.patch
new file mode 100644 (file)
index 0000000..bef9031
--- /dev/null
@@ -0,0 +1,198 @@
+From 1e626143f021be6b7d5a2b3a13441c8d4779f9ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Sep 2022 02:24:18 +0900
+Subject: debugfs: fix error when writing negative value to atomic_t debugfs
+ file
+
+From: Akinobu Mita <akinobu.mita@gmail.com>
+
+[ Upstream commit d472cf797c4e268613dbce5ec9b95d0bcae19ecb ]
+
+The simple attribute files do not accept a negative value since the commit
+488dac0c9237 ("libfs: fix error cast of negative value in
+simple_attr_write()"), so we have to use a 64-bit value to write a
+negative value for a debugfs file created by debugfs_create_atomic_t().
+
+This restores the previous behaviour by introducing
+DEFINE_DEBUGFS_ATTRIBUTE_SIGNED for a signed value.
+
+Link: https://lkml.kernel.org/r/20220919172418.45257-4-akinobu.mita@gmail.com
+Fixes: 488dac0c9237 ("libfs: fix error cast of negative value in simple_attr_write()")
+Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
+Reported-by: Zhao Gongyi <zhaogongyi@huawei.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Rafael J. Wysocki <rafael@kernel.org>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Wei Yongjun <weiyongjun1@huawei.com>
+Cc: Yicong Yang <yangyicong@hisilicon.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../fault-injection/fault-injection.rst       | 10 +++----
+ fs/debugfs/file.c                             | 28 +++++++++++++++----
+ include/linux/debugfs.h                       | 19 +++++++++++--
+ 3 files changed, 43 insertions(+), 14 deletions(-)
+
+diff --git a/Documentation/fault-injection/fault-injection.rst b/Documentation/fault-injection/fault-injection.rst
+index f47d05ed0d94..47de5006f645 100644
+--- a/Documentation/fault-injection/fault-injection.rst
++++ b/Documentation/fault-injection/fault-injection.rst
+@@ -79,9 +79,7 @@ configuration of fault-injection capabilities.
+ - /sys/kernel/debug/fail*/times:
+       specifies how many times failures may happen at most. A value of -1
+-      means "no limit". Note, though, that this file only accepts unsigned
+-      values. So, if you want to specify -1, you better use 'printf' instead
+-      of 'echo', e.g.: $ printf %#x -1 > times
++      means "no limit".
+ - /sys/kernel/debug/fail*/space:
+@@ -259,7 +257,7 @@ Application Examples
+     echo Y > /sys/kernel/debug/$FAILTYPE/task-filter
+     echo 10 > /sys/kernel/debug/$FAILTYPE/probability
+     echo 100 > /sys/kernel/debug/$FAILTYPE/interval
+-    printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
++    echo -1 > /sys/kernel/debug/$FAILTYPE/times
+     echo 0 > /sys/kernel/debug/$FAILTYPE/space
+     echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
+     echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait
+@@ -313,7 +311,7 @@ Application Examples
+     echo N > /sys/kernel/debug/$FAILTYPE/task-filter
+     echo 10 > /sys/kernel/debug/$FAILTYPE/probability
+     echo 100 > /sys/kernel/debug/$FAILTYPE/interval
+-    printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
++    echo -1 > /sys/kernel/debug/$FAILTYPE/times
+     echo 0 > /sys/kernel/debug/$FAILTYPE/space
+     echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
+     echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait
+@@ -344,7 +342,7 @@ Application Examples
+     echo N > /sys/kernel/debug/$FAILTYPE/task-filter
+     echo 100 > /sys/kernel/debug/$FAILTYPE/probability
+     echo 0 > /sys/kernel/debug/$FAILTYPE/interval
+-    printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
++    echo -1 > /sys/kernel/debug/$FAILTYPE/times
+     echo 0 > /sys/kernel/debug/$FAILTYPE/space
+     echo 1 > /sys/kernel/debug/$FAILTYPE/verbose
+diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
+index 96059af28f50..42bab9270e7d 100644
+--- a/fs/debugfs/file.c
++++ b/fs/debugfs/file.c
+@@ -378,8 +378,8 @@ ssize_t debugfs_attr_read(struct file *file, char __user *buf,
+ }
+ EXPORT_SYMBOL_GPL(debugfs_attr_read);
+-ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+-                       size_t len, loff_t *ppos)
++static ssize_t debugfs_attr_write_xsigned(struct file *file, const char __user *buf,
++                       size_t len, loff_t *ppos, bool is_signed)
+ {
+       struct dentry *dentry = F_DENTRY(file);
+       ssize_t ret;
+@@ -387,12 +387,28 @@ ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+       ret = debugfs_file_get(dentry);
+       if (unlikely(ret))
+               return ret;
+-      ret = simple_attr_write(file, buf, len, ppos);
++      if (is_signed)
++              ret = simple_attr_write_signed(file, buf, len, ppos);
++      else
++              ret = simple_attr_write(file, buf, len, ppos);
+       debugfs_file_put(dentry);
+       return ret;
+ }
++
++ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
++                       size_t len, loff_t *ppos)
++{
++      return debugfs_attr_write_xsigned(file, buf, len, ppos, false);
++}
+ EXPORT_SYMBOL_GPL(debugfs_attr_write);
++ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf,
++                       size_t len, loff_t *ppos)
++{
++      return debugfs_attr_write_xsigned(file, buf, len, ppos, true);
++}
++EXPORT_SYMBOL_GPL(debugfs_attr_write_signed);
++
+ static struct dentry *debugfs_create_mode_unsafe(const char *name, umode_t mode,
+                                       struct dentry *parent, void *value,
+                                       const struct file_operations *fops,
+@@ -748,11 +764,11 @@ static int debugfs_atomic_t_get(void *data, u64 *val)
+       *val = atomic_read((atomic_t *)data);
+       return 0;
+ }
+-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t, debugfs_atomic_t_get,
+                       debugfs_atomic_t_set, "%lld\n");
+-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL,
++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_ro, debugfs_atomic_t_get, NULL,
+                       "%lld\n");
+-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set,
++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_wo, NULL, debugfs_atomic_t_set,
+                       "%lld\n");
+ /**
+diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
+index 2357109a8901..9a87215b5526 100644
+--- a/include/linux/debugfs.h
++++ b/include/linux/debugfs.h
+@@ -45,7 +45,7 @@ struct debugfs_u32_array {
+ extern struct dentry *arch_debugfs_dir;
+-#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)         \
++#define DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, __is_signed)    \
+ static int __fops ## _open(struct inode *inode, struct file *file)    \
+ {                                                                     \
+       __simple_attr_check_format(__fmt, 0ull);                        \
+@@ -56,10 +56,16 @@ static const struct file_operations __fops = {                             \
+       .open    = __fops ## _open,                                     \
+       .release = simple_attr_release,                                 \
+       .read    = debugfs_attr_read,                                   \
+-      .write   = debugfs_attr_write,                                  \
++      .write   = (__is_signed) ? debugfs_attr_write_signed : debugfs_attr_write,      \
+       .llseek  = no_llseek,                                           \
+ }
++#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)         \
++      DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, false)
++
++#define DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt)  \
++      DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, true)
++
+ typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *);
+ #if defined(CONFIG_DEBUG_FS)
+@@ -102,6 +108,8 @@ ssize_t debugfs_attr_read(struct file *file, char __user *buf,
+                       size_t len, loff_t *ppos);
+ ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+                       size_t len, loff_t *ppos);
++ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf,
++                      size_t len, loff_t *ppos);
+ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+                 struct dentry *new_dir, const char *new_name);
+@@ -249,6 +257,13 @@ static inline ssize_t debugfs_attr_write(struct file *file,
+       return -ENODEV;
+ }
++static inline ssize_t debugfs_attr_write_signed(struct file *file,
++                                      const char __user *buf,
++                                      size_t len, loff_t *ppos)
++{
++      return -ENODEV;
++}
++
+ static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+                 struct dentry *new_dir, char *new_name)
+ {
+-- 
+2.35.1
+
diff --git a/queue-5.10/dmaengine-idxd-fix-crc_val-field-for-completion-reco.patch b/queue-5.10/dmaengine-idxd-fix-crc_val-field-for-completion-reco.patch
new file mode 100644 (file)
index 0000000..eca46be
--- /dev/null
@@ -0,0 +1,38 @@
+From b15d35b0f02d38960f57ebc941ce7d1e40c9995b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 17:27:15 -0800
+Subject: dmaengine: idxd: Fix crc_val field for completion record
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit dc901d98b1fe6e52ab81cd3e0879379168e06daa ]
+
+The crc_val in the completion record should be 64 bits and not 32 bits.
+
+Fixes: 4ac823e9cd85 ("dmaengine: idxd: fix delta_rec and crc size field for completion record")
+Reported-by: Nirav N Shah <nirav.n.shah@intel.com>
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20221111012715.2031481-1-fenghua.yu@intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/idxd.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/uapi/linux/idxd.h b/include/uapi/linux/idxd.h
+index 9d9ecc0f4c38..f086c5579006 100644
+--- a/include/uapi/linux/idxd.h
++++ b/include/uapi/linux/idxd.h
+@@ -188,7 +188,7 @@ struct dsa_completion_record {
+               };
+               uint32_t        delta_rec_size;
+-              uint32_t        crc_val;
++              uint64_t        crc_val;
+               /* DIF check & strip */
+               struct {
+-- 
+2.35.1
+
diff --git a/queue-5.10/docs-fault-injection-fix-non-working-usage-of-negati.patch b/queue-5.10/docs-fault-injection-fix-non-working-usage-of-negati.patch
new file mode 100644 (file)
index 0000000..3e4a2c4
--- /dev/null
@@ -0,0 +1,97 @@
+From 81cc1785ec6ef408bdc68073495fe6696110285a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 14:58:41 +0200
+Subject: docs: fault-injection: fix non-working usage of negative values
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 005747526d4f3c2ec995891e95cb7625161022f9 ]
+
+Fault injection uses debugfs in a way that the provided values via sysfs
+are interpreted as u64. Providing negative numbers results in an error:
+
+/sys/kernel/debug/fail_function# echo -1 > times
+sh: write error: Invalid argument
+
+Update the docs and examples to use "printf %#x <val>" in these cases.
+For "retval", reword the paragraph a little and fix a typo.
+
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Link: https://lore.kernel.org/r/20210603125841.27436-1-wsa+renesas@sang-engineering.com
+Signed-off-by: Jonathan Corbet <corbet@lwn.net>
+Stable-dep-of: d472cf797c4e ("debugfs: fix error when writing negative value to atomic_t debugfs file")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../fault-injection/fault-injection.rst       | 24 +++++++++++--------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/Documentation/fault-injection/fault-injection.rst b/Documentation/fault-injection/fault-injection.rst
+index 31ecfe44e5b4..f47d05ed0d94 100644
+--- a/Documentation/fault-injection/fault-injection.rst
++++ b/Documentation/fault-injection/fault-injection.rst
+@@ -78,8 +78,10 @@ configuration of fault-injection capabilities.
+ - /sys/kernel/debug/fail*/times:
+-      specifies how many times failures may happen at most.
+-      A value of -1 means "no limit".
++      specifies how many times failures may happen at most. A value of -1
++      means "no limit". Note, though, that this file only accepts unsigned
++      values. So, if you want to specify -1, you better use 'printf' instead
++      of 'echo', e.g.: $ printf %#x -1 > times
+ - /sys/kernel/debug/fail*/space:
+@@ -167,11 +169,13 @@ configuration of fault-injection capabilities.
+       - ERRNO: retval must be -1 to -MAX_ERRNO (-4096).
+       - ERR_NULL: retval must be 0 or -1 to -MAX_ERRNO (-4096).
+-- /sys/kernel/debug/fail_function/<functiuon-name>/retval:
++- /sys/kernel/debug/fail_function/<function-name>/retval:
+-      specifies the "error" return value to inject to the given
+-      function for given function. This will be created when
+-      user specifies new injection entry.
++      specifies the "error" return value to inject to the given function.
++      This will be created when the user specifies a new injection entry.
++      Note that this file only accepts unsigned values. So, if you want to
++      use a negative errno, you better use 'printf' instead of 'echo', e.g.:
++      $ printf %#x -12 > retval
+ Boot option
+ ^^^^^^^^^^^
+@@ -255,7 +259,7 @@ Application Examples
+     echo Y > /sys/kernel/debug/$FAILTYPE/task-filter
+     echo 10 > /sys/kernel/debug/$FAILTYPE/probability
+     echo 100 > /sys/kernel/debug/$FAILTYPE/interval
+-    echo -1 > /sys/kernel/debug/$FAILTYPE/times
++    printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
+     echo 0 > /sys/kernel/debug/$FAILTYPE/space
+     echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
+     echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait
+@@ -309,7 +313,7 @@ Application Examples
+     echo N > /sys/kernel/debug/$FAILTYPE/task-filter
+     echo 10 > /sys/kernel/debug/$FAILTYPE/probability
+     echo 100 > /sys/kernel/debug/$FAILTYPE/interval
+-    echo -1 > /sys/kernel/debug/$FAILTYPE/times
++    printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
+     echo 0 > /sys/kernel/debug/$FAILTYPE/space
+     echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
+     echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait
+@@ -336,11 +340,11 @@ Application Examples
+     FAILTYPE=fail_function
+     FAILFUNC=open_ctree
+     echo $FAILFUNC > /sys/kernel/debug/$FAILTYPE/inject
+-    echo -12 > /sys/kernel/debug/$FAILTYPE/$FAILFUNC/retval
++    printf %#x -12 > /sys/kernel/debug/$FAILTYPE/$FAILFUNC/retval
+     echo N > /sys/kernel/debug/$FAILTYPE/task-filter
+     echo 100 > /sys/kernel/debug/$FAILTYPE/probability
+     echo 0 > /sys/kernel/debug/$FAILTYPE/interval
+-    echo -1 > /sys/kernel/debug/$FAILTYPE/times
++    printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
+     echo 0 > /sys/kernel/debug/$FAILTYPE/space
+     echo 1 > /sys/kernel/debug/$FAILTYPE/verbose
+-- 
+2.35.1
+
diff --git a/queue-5.10/drbd-fix-an-invalid-memory-access-caused-by-incorrec.patch b/queue-5.10/drbd-fix-an-invalid-memory-access-caused-by-incorrec.patch
new file mode 100644 (file)
index 0000000..8e3cf34
--- /dev/null
@@ -0,0 +1,63 @@
+From 36b098452669221592e7d44f8172f4fb57ff2367 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Apr 2022 21:04:44 +0200
+Subject: drbd: fix an invalid memory access caused by incorrect use of list
+ iterator
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xiaomeng Tong <xiam0nd.tong@gmail.com>
+
+[ Upstream commit ae4d37b5df749926891583d42a6801b5da11e3c1 ]
+
+The bug is here:
+       idr_remove(&connection->peer_devices, vnr);
+
+If the previous for_each_connection() don't exit early (no goto hit
+inside the loop), the iterator 'connection' after the loop will be a
+bogus pointer to an invalid structure object containing the HEAD
+(&resource->connections). As a result, the use of 'connection' above
+will lead to a invalid memory access (including a possible invalid free
+as idr_remove could call free_layer).
+
+The original intention should have been to remove all peer_devices,
+but the following lines have already done the work. So just remove
+this line and the unneeded label, to fix this bug.
+
+Cc: stable@vger.kernel.org
+Fixes: c06ece6ba6f1b ("drbd: Turn connection->volumes into connection->peer_devices")
+Signed-off-by: Xiaomeng Tong <xiam0nd.tong@gmail.com>
+Reviewed-by: Christoph Böhmwalder <christoph.boehmwalder@linbit.com>
+Reviewed-by: Lars Ellenberg <lars.ellenberg@linbit.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/drbd/drbd_main.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
+index 51450f7c81af..420bdaf8c356 100644
+--- a/drivers/block/drbd/drbd_main.c
++++ b/drivers/block/drbd/drbd_main.c
+@@ -2819,7 +2819,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
+       if (init_submitter(device)) {
+               err = ERR_NOMEM;
+-              goto out_idr_remove_vol;
++              goto out_idr_remove_from_resource;
+       }
+       add_disk(disk);
+@@ -2836,8 +2836,6 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
+       drbd_debugfs_device_add(device);
+       return NO_ERROR;
+-out_idr_remove_vol:
+-      idr_remove(&connection->peer_devices, vnr);
+ out_idr_remove_from_resource:
+       for_each_connection_safe(connection, n, resource) {
+               peer_device = idr_remove(&connection->peer_devices, vnr);
+-- 
+2.35.1
+
diff --git a/queue-5.10/drivers-dio-fix-possible-memory-leak-in-dio_init.patch b/queue-5.10/drivers-dio-fix-possible-memory-leak-in-dio_init.patch
new file mode 100644 (file)
index 0000000..ba29df3
--- /dev/null
@@ -0,0 +1,60 @@
+From 75ffda1d80566453e475f330a128007ad2be3e9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 14:40:36 +0800
+Subject: drivers: dio: fix possible memory leak in dio_init()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit e63e99397b2613d50a5f4f02ed07307e67a190f1 ]
+
+If device_register() returns error, the 'dev' and name needs be
+freed. Add a release function, and then call put_device() in the
+error path, so the name is freed in kobject_cleanup() and to the
+'dev' is freed in release function.
+
+Fixes: 2e4c77bea3d8 ("m68k: dio - Kill warn_unused_result warnings")
+Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221109064036.1835346-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dio/dio.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
+index 193b40e7aec0..1414a1c81834 100644
+--- a/drivers/dio/dio.c
++++ b/drivers/dio/dio.c
+@@ -110,6 +110,12 @@ static char dio_no_name[] = { 0 };
+ #endif /* CONFIG_DIO_CONSTANTS */
++static void dio_dev_release(struct device *dev)
++{
++      struct dio_dev *ddev = container_of(dev, typeof(struct dio_dev), dev);
++      kfree(ddev);
++}
++
+ int __init dio_find(int deviceid)
+ {
+       /* Called to find a DIO device before the full bus scan has run.
+@@ -224,6 +230,7 @@ static int __init dio_init(void)
+               dev->bus = &dio_bus;
+               dev->dev.parent = &dio_bus.dev;
+               dev->dev.bus = &dio_bus_type;
++              dev->dev.release = dio_dev_release;
+               dev->scode = scode;
+               dev->resource.start = pa;
+               dev->resource.end = pa + DIO_SIZE(scode, va);
+@@ -251,6 +258,7 @@ static int __init dio_init(void)
+               if (error) {
+                       pr_err("DIO: Error registering device %s\n",
+                              dev->name);
++                      put_device(&dev->dev);
+                       continue;
+               }
+               error = dio_create_sysfs_dev_files(dev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/drivers-mcb-fix-resource-leak-in-mcb_probe.patch b/queue-5.10/drivers-mcb-fix-resource-leak-in-mcb_probe.patch
new file mode 100644 (file)
index 0000000..7478132
--- /dev/null
@@ -0,0 +1,41 @@
+From 784fd8a03d2614ecf8f2d64160d91ef65a7bbe81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 01:38:49 -0800
+Subject: drivers: mcb: fix resource leak in mcb_probe()
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit d7237462561fcd224fa687c56ccb68629f50fc0d ]
+
+When probe hook function failed in mcb_probe(), it doesn't put the device.
+Compiled test only.
+
+Fixes: 7bc364097a89 ("mcb: Acquire reference to device in probe")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Signed-off-by: Johannes Thumshirn <jth@kernel.org>
+Link: https://lore.kernel.org/r/9f87de36bfb85158b506cb78c6fc9db3f6a3bad1.1669624063.git.johannes.thumshirn@wdc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mcb/mcb-core.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c
+index 38cc8340e817..8b8cd751fe9a 100644
+--- a/drivers/mcb/mcb-core.c
++++ b/drivers/mcb/mcb-core.c
+@@ -71,8 +71,10 @@ static int mcb_probe(struct device *dev)
+       get_device(dev);
+       ret = mdrv->probe(mdev, found_id);
+-      if (ret)
++      if (ret) {
+               module_put(carrier_mod);
++              put_device(dev);
++      }
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/drivers-md-md-bitmap-check-the-return-value-of-md_bi.patch b/queue-5.10/drivers-md-md-bitmap-check-the-return-value-of-md_bi.patch
new file mode 100644 (file)
index 0000000..1d950cc
--- /dev/null
@@ -0,0 +1,65 @@
+From c70b3885490c1fe6a51e15d4d7a3b38cb5867e32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Sep 2022 16:33:05 -0700
+Subject: drivers/md/md-bitmap: check the return value of
+ md_bitmap_get_counter()
+
+From: Li Zhong <floridsleeves@gmail.com>
+
+[ Upstream commit 3bd548e5b819b8c0f2c9085de775c5c7bff9052f ]
+
+Check the return value of md_bitmap_get_counter() in case it returns
+NULL pointer, which will result in a null pointer dereference.
+
+v2: update the check to include other dereference
+
+Signed-off-by: Li Zhong <floridsleeves@gmail.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-bitmap.c | 27 +++++++++++++++------------
+ 1 file changed, 15 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index d377ea060925..4e52fcf98d59 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -2196,20 +2196,23 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+               if (set) {
+                       bmc_new = md_bitmap_get_counter(&bitmap->counts, block, &new_blocks, 1);
+-                      if (*bmc_new == 0) {
+-                              /* need to set on-disk bits too. */
+-                              sector_t end = block + new_blocks;
+-                              sector_t start = block >> chunkshift;
+-                              start <<= chunkshift;
+-                              while (start < end) {
+-                                      md_bitmap_file_set_bit(bitmap, block);
+-                                      start += 1 << chunkshift;
++                      if (bmc_new) {
++                              if (*bmc_new == 0) {
++                                      /* need to set on-disk bits too. */
++                                      sector_t end = block + new_blocks;
++                                      sector_t start = block >> chunkshift;
++
++                                      start <<= chunkshift;
++                                      while (start < end) {
++                                              md_bitmap_file_set_bit(bitmap, block);
++                                              start += 1 << chunkshift;
++                                      }
++                                      *bmc_new = 2;
++                                      md_bitmap_count_page(&bitmap->counts, block, 1);
++                                      md_bitmap_set_pending(&bitmap->counts, block);
+                               }
+-                              *bmc_new = 2;
+-                              md_bitmap_count_page(&bitmap->counts, block, 1);
+-                              md_bitmap_set_pending(&bitmap->counts, block);
++                              *bmc_new |= NEEDED_MASK;
+                       }
+-                      *bmc_new |= NEEDED_MASK;
+                       if (new_blocks < old_blocks)
+                               old_blocks = new_blocks;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.10/drivers-net-qlcnic-fix-potential-memory-leak-in-qlcn.patch b/queue-5.10/drivers-net-qlcnic-fix-potential-memory-leak-in-qlcn.patch
new file mode 100644 (file)
index 0000000..306cdd9
--- /dev/null
@@ -0,0 +1,38 @@
+From 183433cf2cd9db6c1fb1bb2104776bb86edbfd08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 08:54:10 +0000
+Subject: drivers: net: qlcnic: Fix potential memory leak in
+ qlcnic_sriov_init()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 01de1123322e4fe1bbd0fcdf0982511b55519c03 ]
+
+If vp alloc failed in qlcnic_sriov_init(), all previously allocated vp
+needs to be freed.
+
+Fixes: f197a7aa6288 ("qlcnic: VF-PF communication channel implementation")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+index 8367891bfb13..e864c453c5e6 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+@@ -221,6 +221,8 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs)
+       return 0;
+ qlcnic_destroy_async_wq:
++      while (i--)
++              kfree(sriov->vf_info[i].vp);
+       destroy_workqueue(bc->bc_async_wq);
+ qlcnic_destroy_trans_wq:
+-- 
+2.35.1
+
diff --git a/queue-5.10/drivers-soc-ti-knav_qmss_queue-mark-knav_acc_firmwar.patch b/queue-5.10/drivers-soc-ti-knav_qmss_queue-mark-knav_acc_firmwar.patch
new file mode 100644 (file)
index 0000000..70ad6d6
--- /dev/null
@@ -0,0 +1,42 @@
+From 8e25669829e302d26b42b7d8c1863968329202d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Oct 2022 23:32:12 +0800
+Subject: drivers: soc: ti: knav_qmss_queue: Mark knav_acc_firmwares as static
+
+From: Chen Jiahao <chenjiahao16@huawei.com>
+
+[ Upstream commit adf85adc2a7199b41e7a4da083bd17274a3d6969 ]
+
+There is a sparse warning shown below:
+
+drivers/soc/ti/knav_qmss_queue.c:70:12: warning: symbol
+'knav_acc_firmwares' was not declared. Should it be static?
+
+Since 'knav_acc_firmwares' is only called within knav_qmss_queue.c,
+mark it as static to fix the warning.
+
+Fixes: 96ee19becc3b ("soc: ti: add firmware file name as part of the driver")
+Signed-off-by: Chen Jiahao <chenjiahao16@huawei.com>
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Link: https://lore.kernel.org/r/20221019153212.72350-1-chenjiahao16@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/ti/knav_qmss_queue.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
+index 53e36d4328d1..baab7d558a69 100644
+--- a/drivers/soc/ti/knav_qmss_queue.c
++++ b/drivers/soc/ti/knav_qmss_queue.c
+@@ -67,7 +67,7 @@ static DEFINE_MUTEX(knav_dev_lock);
+  * Newest followed by older ones. Search is done from start of the array
+  * until a firmware file is found.
+  */
+-const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
++static const char * const knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
+ static bool device_ready;
+ bool knav_qmss_device_ready(void)
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-amd-display-fix-array-index-out-of-bound-error-i.patch b/queue-5.10/drm-amd-display-fix-array-index-out-of-bound-error-i.patch
new file mode 100644 (file)
index 0000000..4a7d29d
--- /dev/null
@@ -0,0 +1,68 @@
+From 2ef070cfa2a6f85b772170af0d0f97f23282454a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 15:35:53 -0400
+Subject: drm/amd/display: fix array index out of bound error in bios parser
+
+From: Aurabindo Pillai <aurabindo.pillai@amd.com>
+
+[ Upstream commit 4fc1ba4aa589ca267468ad23fedef37562227d32 ]
+
+[Why&How]
+Firmware headers dictate that gpio_pin array only has a size of 8. The
+count returned from vbios however is greater than 8.
+
+Fix this by not using array indexing but incrementing the pointer since
+gpio_pin definition in atomfirmware.h is hardcoded to size 8
+
+Reviewed-by: Martin Leung <Martin.Leung@amd.com>
+Acked-by: Tom Chung <chiahsuan.chung@amd.com>
+Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dc/bios/bios_parser2.c   | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+index 29d64e7e304f..930d2b7d3448 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -352,6 +352,7 @@ static enum bp_result get_gpio_i2c_info(
+       uint32_t count = 0;
+       unsigned int table_index = 0;
+       bool find_valid = false;
++      struct atom_gpio_pin_assignment *pin;
+       if (!info)
+               return BP_RESULT_BADINPUT;
+@@ -379,20 +380,17 @@ static enum bp_result get_gpio_i2c_info(
+                       - sizeof(struct atom_common_table_header))
+                               / sizeof(struct atom_gpio_pin_assignment);
++      pin = (struct atom_gpio_pin_assignment *) header->gpio_pin;
++
+       for (table_index = 0; table_index < count; table_index++) {
+-              if (((record->i2c_id & I2C_HW_CAP) == (
+-              header->gpio_pin[table_index].gpio_id &
+-                                              I2C_HW_CAP)) &&
+-              ((record->i2c_id & I2C_HW_ENGINE_ID_MASK)  ==
+-              (header->gpio_pin[table_index].gpio_id &
+-                                      I2C_HW_ENGINE_ID_MASK)) &&
+-              ((record->i2c_id & I2C_HW_LANE_MUX) ==
+-              (header->gpio_pin[table_index].gpio_id &
+-                                              I2C_HW_LANE_MUX))) {
++              if (((record->i2c_id & I2C_HW_CAP)                              == (pin->gpio_id & I2C_HW_CAP)) &&
++                  ((record->i2c_id & I2C_HW_ENGINE_ID_MASK)   == (pin->gpio_id & I2C_HW_ENGINE_ID_MASK)) &&
++                  ((record->i2c_id & I2C_HW_LANE_MUX)                 == (pin->gpio_id & I2C_HW_LANE_MUX))) {
+                       /* still valid */
+                       find_valid = true;
+                       break;
+               }
++              pin = (struct atom_gpio_pin_assignment *)((uint8_t *)pin + sizeof(struct atom_gpio_pin_assignment));
+       }
+       /* If we don't find the entry that we are looking for then
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-amd-display-prevent-memory-leak.patch b/queue-5.10/drm-amd-display-prevent-memory-leak.patch
new file mode 100644 (file)
index 0000000..8ddfad4
--- /dev/null
@@ -0,0 +1,73 @@
+From eb58d50113ceca826cafe8be9e426f48a546116d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Oct 2022 17:54:05 +0800
+Subject: drm/amd/display: prevent memory leak
+
+From: gehao <gehao@kylinos.cn>
+
+[ Upstream commit d232afb1f3417ae8194ccf19ad3a8360e70e104e ]
+
+In dce6(0,1,4)_create_resource_pool and dce80_create_resource_pool
+the allocated memory should be released if construct pool fails.
+
+Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: gehao <gehao@kylinos.cn>
+Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c | 3 +++
+ drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c | 2 ++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
+index 5a5a9cb77acb..bcdd8a958fc0 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
+@@ -1132,6 +1132,7 @@ struct resource_pool *dce60_create_resource_pool(
+       if (dce60_construct(num_virtual_links, dc, pool))
+               return &pool->base;
++      kfree(pool);
+       BREAK_TO_DEBUGGER();
+       return NULL;
+ }
+@@ -1329,6 +1330,7 @@ struct resource_pool *dce61_create_resource_pool(
+       if (dce61_construct(num_virtual_links, dc, pool))
+               return &pool->base;
++      kfree(pool);
+       BREAK_TO_DEBUGGER();
+       return NULL;
+ }
+@@ -1522,6 +1524,7 @@ struct resource_pool *dce64_create_resource_pool(
+       if (dce64_construct(num_virtual_links, dc, pool))
+               return &pool->base;
++      kfree(pool);
+       BREAK_TO_DEBUGGER();
+       return NULL;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+index a19be9de2df7..2eefa07762ae 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+@@ -1141,6 +1141,7 @@ struct resource_pool *dce80_create_resource_pool(
+       if (dce80_construct(num_virtual_links, dc, pool))
+               return &pool->base;
++      kfree(pool);
+       BREAK_TO_DEBUGGER();
+       return NULL;
+ }
+@@ -1338,6 +1339,7 @@ struct resource_pool *dce81_create_resource_pool(
+       if (dce81_construct(num_virtual_links, dc, pool))
+               return &pool->base;
++      kfree(pool);
+       BREAK_TO_DEBUGGER();
+       return NULL;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-amd-pm-smu11-baco-is-supported-when-it-s-in-baco.patch b/queue-5.10/drm-amd-pm-smu11-baco-is-supported-when-it-s-in-baco.patch
new file mode 100644 (file)
index 0000000..5b0ebf0
--- /dev/null
@@ -0,0 +1,43 @@
+From d30b88c661d2baf251926b18b1de5e30a453cefa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 17:33:24 +0800
+Subject: drm/amd/pm/smu11: BACO is supported when it's in BACO state
+
+From: Guchun Chen <guchun.chen@amd.com>
+
+[ Upstream commit 6dca7efe6e522bf213c7dab691fa580d82f48f74 ]
+
+Return true early if ASIC is in BACO state already, no need
+to talk to SMU. It can fix the issue that driver was not
+calling BACO exit at all in runtime pm resume, and a timing
+issue leading to a PCI AER error happened eventually.
+
+Fixes: 8795e182b02d ("PCI/portdrv: Don't disable AER reporting in get_port_device_capability()")
+Suggested-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Guchun Chen <guchun.chen@amd.com>
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Reviewed-by: Evan Quan <evan.quan@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+index e646f5931d79..89f20497c14f 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+@@ -1476,6 +1476,10 @@ bool smu_v11_0_baco_is_support(struct smu_context *smu)
+       if (!smu_baco->platform_support)
+               return false;
++      /* return true if ASIC is in BACO state already */
++      if (smu_v11_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER)
++              return true;
++
+       /* Arcturus does not support this bit mask */
+       if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) &&
+          !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT))
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-amdgpu-fix-pci-device-refcount-leak-in-amdgpu_at.patch b/queue-5.10/drm-amdgpu-fix-pci-device-refcount-leak-in-amdgpu_at.patch
new file mode 100644 (file)
index 0000000..ff85ed5
--- /dev/null
@@ -0,0 +1,40 @@
+From f3efac985259f153239d940dd11f8a1682818406 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 19:30:43 +0800
+Subject: drm/amdgpu: Fix PCI device refcount leak in amdgpu_atrm_get_bios()
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit ca54639c7752edf1304d92ff4d0c049d4efc9ba0 ]
+
+As comment of pci_get_class() says, it returns a pci_device with its
+refcount increased and decreased the refcount for the input parameter
+@from if it is not NULL.
+
+If we break the loop in amdgpu_atrm_get_bios() with 'pdev' not NULL, we
+need to call pci_dev_put() to decrease the refcount. Add the missing
+pci_dev_put() to avoid refcount leak.
+
+Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+index 6333cada1e09..4b568ee93243 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+@@ -313,6 +313,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
+       if (!found)
+               return false;
++      pci_dev_put(pdev);
+       adev->bios = kmalloc(size, GFP_KERNEL);
+       if (!adev->bios) {
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-amdgpu-fix-pci-device-refcount-leak.patch b/queue-5.10/drm-amdgpu-fix-pci-device-refcount-leak.patch
new file mode 100644 (file)
index 0000000..208e770
--- /dev/null
@@ -0,0 +1,58 @@
+From f2e9a9b2a9f9c9b61066a1b7a1e3ce9d42ef1fc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 23:00:03 +0800
+Subject: drm/amdgpu: fix pci device refcount leak
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit b85e285e3d6352b02947fc1b72303673dfacb0aa ]
+
+As comment of pci_get_domain_bus_and_slot() says, it returns
+a pci device with refcount increment, when finish using it,
+the caller must decrement the reference count by calling
+pci_dev_put().
+
+So before returning from amdgpu_device_resume|suspend_display_audio(),
+pci_dev_put() is called to avoid refcount leak.
+
+Fixes: 3f12acc8d6d4 ("drm/amdgpu: put the audio codec into suspend state before gpu reset V3")
+Reviewed-by: Evan Quan <evan.quan@amd.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index bde0496d2f15..8bd887fb6e63 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -4443,6 +4443,8 @@ static void amdgpu_device_resume_display_audio(struct amdgpu_device *adev)
+               pm_runtime_enable(&(p->dev));
+               pm_runtime_resume(&(p->dev));
+       }
++
++      pci_dev_put(p);
+ }
+ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
+@@ -4481,6 +4483,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
+               if (expires < ktime_get_mono_fast_ns()) {
+                       dev_warn(adev->dev, "failed to suspend display audio\n");
++                      pci_dev_put(p);
+                       /* TODO: abort the succeeding gpu reset? */
+                       return -ETIMEDOUT;
+               }
+@@ -4488,6 +4491,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
+       pm_runtime_disable(&(p->dev));
++      pci_dev_put(p);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-amdgpu-fix-type-of-second-parameter-in-odn_edit_.patch b/queue-5.10/drm-amdgpu-fix-type-of-second-parameter-in-odn_edit_.patch
new file mode 100644 (file)
index 0000000..0d7dacf
--- /dev/null
@@ -0,0 +1,78 @@
+From 8e91e89776fdf1567b22059e483045636b3bd2fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 08:25:40 -0700
+Subject: drm/amdgpu: Fix type of second parameter in odn_edit_dpm_table()
+ callback
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit e4d0ef752081e7aa6ffb7ccac11c499c732a2e05 ]
+
+With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
+indirect call targets are validated against the expected function
+pointer prototype to make sure the call target is valid to help mitigate
+ROP attacks. If they are not identical, there is a failure at run time,
+which manifests as either a kernel panic or thread getting killed. A
+proposed warning in clang aims to catch these at compile time, which
+reveals:
+
+  drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:3008:29: error: incompatible function pointer types initializing 'int (*)(void *, uint32_t, long *, uint32_t)' (aka 'int (*)(void *, unsigned int, long *, unsigned int)') with an expression of type 'int (void *, enum PP_OD_DPM_TABLE_COMMAND, long *, uint32_t)' (aka 'int (void *, enum PP_OD_DPM_TABLE_COMMAND, long *, unsigned int)') [-Werror,-Wincompatible-function-pointer-types-strict]
+          .odn_edit_dpm_table      = smu_od_edit_dpm_table,
+                                     ^~~~~~~~~~~~~~~~~~~~~
+  1 error generated.
+
+There are only two implementations of ->odn_edit_dpm_table() in 'struct
+amd_pm_funcs': smu_od_edit_dpm_table() and pp_odn_edit_dpm_table(). One
+has a second parameter type of 'enum PP_OD_DPM_TABLE_COMMAND' and the
+other uses 'u32'. Ultimately, smu_od_edit_dpm_table() calls
+->od_edit_dpm_table() from 'struct pptable_funcs' and
+pp_odn_edit_dpm_table() calls ->odn_edit_dpm_table() from 'struct
+pp_hwmgr_func', which both have a second parameter type of 'enum
+PP_OD_DPM_TABLE_COMMAND'.
+
+Update the type parameter in both the prototype in 'struct amd_pm_funcs'
+and pp_odn_edit_dpm_table() to 'enum PP_OD_DPM_TABLE_COMMAND', which
+cleans up the warning.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1750
+Reported-by: Sami Tolvanen <samitolvanen@google.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/include/kgd_pp_interface.h   | 3 ++-
+ drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+index 94132c70d7af..5e8876ad1a1b 100644
+--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
++++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+@@ -282,7 +282,8 @@ struct amd_pm_funcs {
+       int (*get_power_profile_mode)(void *handle, char *buf);
+       int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
+       int (*set_fine_grain_clk_vol)(void *handle, uint32_t type, long *input, uint32_t size);
+-      int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size);
++      int (*odn_edit_dpm_table)(void *handle, enum PP_OD_DPM_TABLE_COMMAND type,
++                                long *input, uint32_t size);
+       int (*set_mp1_state)(void *handle, enum pp_mp1_state mp1_state);
+       int (*smu_i2c_bus_access)(void *handle, bool acquire);
+ /* export to DC */
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+index eab9768029c1..a98ea29b2fd5 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+@@ -924,7 +924,8 @@ static int pp_set_fine_grain_clk_vol(void *handle, uint32_t type, long *input, u
+       return hwmgr->hwmgr_func->set_fine_grain_clk_vol(hwmgr, type, input, size);
+ }
+-static int pp_odn_edit_dpm_table(void *handle, uint32_t type, long *input, uint32_t size)
++static int pp_odn_edit_dpm_table(void *handle, enum PP_OD_DPM_TABLE_COMMAND type,
++                               long *input, uint32_t size)
+ {
+       struct pp_hwmgr *hwmgr = handle;
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-amdgpu-fix-type-of-second-parameter-in-trans_msg.patch b/queue-5.10/drm-amdgpu-fix-type-of-second-parameter-in-trans_msg.patch
new file mode 100644 (file)
index 0000000..b66f2de
--- /dev/null
@@ -0,0 +1,66 @@
+From 0cee55e73d73a91cf9e080ac1ca7bb0136dd13c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 08:25:39 -0700
+Subject: drm/amdgpu: Fix type of second parameter in trans_msg() callback
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit f0d0f1087333714ee683cc134a95afe331d7ddd9 ]
+
+With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
+indirect call targets are validated against the expected function
+pointer prototype to make sure the call target is valid to help mitigate
+ROP attacks. If they are not identical, there is a failure at run time,
+which manifests as either a kernel panic or thread getting killed. A
+proposed warning in clang aims to catch these at compile time, which
+reveals:
+
+  drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c:412:15: error: incompatible function pointer types initializing 'void (*)(struct amdgpu_device *, u32, u32, u32, u32)' (aka 'void (*)(struct amdgpu_device *, unsigned int, unsigned int, unsigned int, unsigned int)') with an expression of type 'void (struct amdgpu_device *, enum idh_request, u32, u32, u32)' (aka 'void (struct amdgpu_device *, enum idh_request, unsigned int, unsigned int, unsigned int)') [-Werror,-Wincompatible-function-pointer-types-strict]
+          .trans_msg = xgpu_ai_mailbox_trans_msg,
+                      ^~~~~~~~~~~~~~~~~~~~~~~~~
+  1 error generated.
+
+  drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c:435:15: error: incompatible function pointer types initializing 'void (*)(struct amdgpu_device *, u32, u32, u32, u32)' (aka 'void (*)(struct amdgpu_device *, unsigned int, unsigned int, unsigned int, unsigned int)') with an expression of type 'void (struct amdgpu_device *, enum idh_request, u32, u32, u32)' (aka 'void (struct amdgpu_device *, enum idh_request, unsigned int, unsigned int, unsigned int)') [-Werror,-Wincompatible-function-pointer-types-strict]
+          .trans_msg = xgpu_nv_mailbox_trans_msg,
+                      ^~~~~~~~~~~~~~~~~~~~~~~~~
+  1 error generated.
+
+The type of the second parameter in the prototype should be 'enum
+idh_request' instead of 'u32'. Update it to clear up the warnings.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1750
+Reported-by: Sami Tolvanen <samitolvanen@google.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+index aea49bad914f..fbd92fff8b06 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+@@ -62,6 +62,8 @@ struct amdgpu_vf_error_buffer {
+       uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE];
+ };
++enum idh_request;
++
+ /**
+  * struct amdgpu_virt_ops - amdgpu device virt operations
+  */
+@@ -71,7 +73,8 @@ struct amdgpu_virt_ops {
+       int (*req_init_data)(struct amdgpu_device *adev);
+       int (*reset_gpu)(struct amdgpu_device *adev);
+       int (*wait_reset)(struct amdgpu_device *adev);
+-      void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
++      void (*trans_msg)(struct amdgpu_device *adev, enum idh_request req,
++                        u32 data1, u32 data2, u32 data3);
+ };
+ /*
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-bridge-adv7533-remove-dynamic-lane-switching-fro.patch b/queue-5.10/drm-bridge-adv7533-remove-dynamic-lane-switching-fro.patch
new file mode 100644 (file)
index 0000000..f8dd718
--- /dev/null
@@ -0,0 +1,228 @@
+From 956f4481815ec6e6c3215b5284b78b4ec8edc47e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Oct 2022 14:10:49 -0700
+Subject: drm/bridge: adv7533: remove dynamic lane switching from adv7533
+ bridge
+
+From: Abhinav Kumar <quic_abhinavk@quicinc.com>
+
+[ Upstream commit 9a0cdcd6649b76f0b7ceec0e55b0a718321e34d3 ]
+
+adv7533 bridge tries to dynamically switch lanes based on the
+mode by detaching and attaching the mipi dsi device.
+
+This approach is incorrect because this method of dynamic switch of
+detaching and attaching the mipi dsi device also results in removing
+and adding the component which is not necessary.
+
+This approach is also prone to deadlocks. So for example, on the
+db410c whenever this path is executed with lockdep enabled,
+this results in a deadlock due to below ordering of locks.
+
+-> #1 (crtc_ww_class_acquire){+.+.}-{0:0}:
+        lock_acquire+0x6c/0x90
+        drm_modeset_acquire_init+0xf4/0x150
+        drmm_mode_config_init+0x220/0x770
+        msm_drm_bind+0x13c/0x654
+        try_to_bring_up_aggregate_device+0x164/0x1d0
+        __component_add+0xa8/0x174
+        component_add+0x18/0x2c
+        dsi_dev_attach+0x24/0x30
+        dsi_host_attach+0x98/0x14c
+        devm_mipi_dsi_attach+0x38/0xb0
+        adv7533_attach_dsi+0x8c/0x110
+        adv7511_probe+0x5a0/0x930
+        i2c_device_probe+0x30c/0x350
+        really_probe.part.0+0x9c/0x2b0
+        __driver_probe_device+0x98/0x144
+        driver_probe_device+0xac/0x14c
+        __device_attach_driver+0xbc/0x124
+        bus_for_each_drv+0x78/0xd0
+        __device_attach+0xa8/0x1c0
+        device_initial_probe+0x18/0x24
+        bus_probe_device+0xa0/0xac
+        deferred_probe_work_func+0x90/0xd0
+        process_one_work+0x28c/0x6b0
+        worker_thread+0x240/0x444
+        kthread+0x110/0x114
+        ret_from_fork+0x10/0x20
+
+-> #0 (component_mutex){+.+.}-{3:3}:
+        __lock_acquire+0x1280/0x20ac
+        lock_acquire.part.0+0xe0/0x230
+        lock_acquire+0x6c/0x90
+        __mutex_lock+0x84/0x400
+        mutex_lock_nested+0x3c/0x70
+        component_del+0x34/0x170
+        dsi_dev_detach+0x24/0x30
+        dsi_host_detach+0x20/0x64
+        mipi_dsi_detach+0x2c/0x40
+        adv7533_mode_set+0x64/0x90
+        adv7511_bridge_mode_set+0x210/0x214
+        drm_bridge_chain_mode_set+0x5c/0x84
+        crtc_set_mode+0x18c/0x1dc
+        drm_atomic_helper_commit_modeset_disables+0x40/0x50
+        msm_atomic_commit_tail+0x1d0/0x6e0
+        commit_tail+0xa4/0x180
+        drm_atomic_helper_commit+0x178/0x3b0
+        drm_atomic_commit+0xa4/0xe0
+        drm_client_modeset_commit_atomic+0x228/0x284
+        drm_client_modeset_commit_locked+0x64/0x1d0
+        drm_client_modeset_commit+0x34/0x60
+        drm_fb_helper_lastclose+0x74/0xcc
+        drm_lastclose+0x3c/0x80
+        drm_release+0xfc/0x114
+        __fput+0x70/0x224
+        ____fput+0x14/0x20
+        task_work_run+0x88/0x1a0
+        do_exit+0x350/0xa50
+        do_group_exit+0x38/0xa4
+        __wake_up_parent+0x0/0x34
+        invoke_syscall+0x48/0x114
+        el0_svc_common.constprop.0+0x60/0x11c
+        do_el0_svc+0x30/0xc0
+        el0_svc+0x58/0x100
+        el0t_64_sync_handler+0x1b0/0x1bc
+        el0t_64_sync+0x18c/0x190
+
+Due to above reasons, remove the dynamic lane switching
+code from adv7533 bridge chip and filter out the modes
+which would need different number of lanes as compared
+to the initialization time using the mode_valid callback.
+
+This can be potentially re-introduced by using the pre_enable()
+callback but this needs to be evaluated first whether such an
+approach will work so this will be done with a separate change.
+
+changes since RFC:
+       - Fix commit text and add TODO comment
+
+changes in v2:
+       - Fix checkpatch formatting errors
+
+Fixes: 62b2f026cd8e ("drm/bridge: adv7533: Change number of DSI lanes dynamically")
+Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/16
+Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Link: https://lore.kernel.org/r/1661797363-7564-1-git-send-email-quic_abhinavk@quicinc.com
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/1665522649-3423-1-git-send-email-quic_abhinavk@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511.h     |  3 ++-
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 18 ++++++++++----
+ drivers/gpu/drm/bridge/adv7511/adv7533.c     | 25 ++++++++++----------
+ 3 files changed, 29 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+index 711061bf3eb7..e95abeb64b93 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+@@ -394,7 +394,8 @@ static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
+ void adv7533_dsi_power_on(struct adv7511 *adv);
+ void adv7533_dsi_power_off(struct adv7511 *adv);
+-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode);
++enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
++                                      const struct drm_display_mode *mode);
+ int adv7533_patch_registers(struct adv7511 *adv);
+ int adv7533_patch_cec_registers(struct adv7511 *adv);
+ int adv7533_attach_dsi(struct adv7511 *adv);
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 430c5e8f0388..6ba860a16e96 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -697,7 +697,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
+ }
+ static enum drm_mode_status adv7511_mode_valid(struct adv7511 *adv7511,
+-                            struct drm_display_mode *mode)
++                            const struct drm_display_mode *mode)
+ {
+       if (mode->clock > 165000)
+               return MODE_CLOCK_HIGH;
+@@ -791,9 +791,6 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
+       regmap_update_bits(adv7511->regmap, 0x17,
+               0x60, (vsync_polarity << 6) | (hsync_polarity << 5));
+-      if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
+-              adv7533_mode_set(adv7511, adj_mode);
+-
+       drm_mode_copy(&adv7511->curr_mode, adj_mode);
+       /*
+@@ -913,6 +910,18 @@ static void adv7511_bridge_mode_set(struct drm_bridge *bridge,
+       adv7511_mode_set(adv, mode, adj_mode);
+ }
++static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge,
++                                                    const struct drm_display_info *info,
++              const struct drm_display_mode *mode)
++{
++      struct adv7511 *adv = bridge_to_adv7511(bridge);
++
++      if (adv->type == ADV7533 || adv->type == ADV7535)
++              return adv7533_mode_valid(adv, mode);
++      else
++              return adv7511_mode_valid(adv, mode);
++}
++
+ static int adv7511_bridge_attach(struct drm_bridge *bridge,
+                                enum drm_bridge_attach_flags flags)
+ {
+@@ -963,6 +972,7 @@ static const struct drm_bridge_funcs adv7511_bridge_funcs = {
+       .enable = adv7511_bridge_enable,
+       .disable = adv7511_bridge_disable,
+       .mode_set = adv7511_bridge_mode_set,
++      .mode_valid = adv7511_bridge_mode_valid,
+       .attach = adv7511_bridge_attach,
+       .detect = adv7511_bridge_detect,
+       .get_edid = adv7511_bridge_get_edid,
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c
+index aa19d5a40e31..f304a5ff8e59 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
+@@ -100,26 +100,27 @@ void adv7533_dsi_power_off(struct adv7511 *adv)
+       regmap_write(adv->regmap_cec, 0x27, 0x0b);
+ }
+-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode)
++enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
++                                      const struct drm_display_mode *mode)
+ {
++      int lanes;
+       struct mipi_dsi_device *dsi = adv->dsi;
+-      int lanes, ret;
+-
+-      if (adv->num_dsi_lanes != 4)
+-              return;
+       if (mode->clock > 80000)
+               lanes = 4;
+       else
+               lanes = 3;
+-      if (lanes != dsi->lanes) {
+-              mipi_dsi_detach(dsi);
+-              dsi->lanes = lanes;
+-              ret = mipi_dsi_attach(dsi);
+-              if (ret)
+-                      dev_err(&dsi->dev, "failed to change host lanes\n");
+-      }
++      /*
++       * TODO: add support for dynamic switching of lanes
++       * by using the bridge pre_enable() op . Till then filter
++       * out the modes which shall need different number of lanes
++       * than what was configured in the device tree.
++       */
++      if (lanes != dsi->lanes)
++              return MODE_BAD;
++
++      return MODE_OK;
+ }
+ int adv7533_patch_registers(struct adv7511 *adv)
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-etnaviv-add-missing-quirks-for-gc300.patch b/queue-5.10/drm-etnaviv-add-missing-quirks-for-gc300.patch
new file mode 100644 (file)
index 0000000..b4b8d9d
--- /dev/null
@@ -0,0 +1,53 @@
+From 0fbcff1cc0e444559c4418d5941acdc1dd90114a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Sep 2022 13:29:38 -0700
+Subject: drm/etnaviv: add missing quirks for GC300
+
+From: Doug Brown <doug@schmorgal.com>
+
+[ Upstream commit cc7d3fb446a91f24978a6aa59cbb578f92e22242 ]
+
+The GC300's features register doesn't specify that a 2D pipe is
+available, and like the GC600, its idle register reports zero bits where
+modules aren't present.
+
+Signed-off-by: Doug Brown <doug@schmorgal.com>
+Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+index 2520b7dad6ce..f3281d56b1d8 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+@@ -408,6 +408,12 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
+       if (gpu->identity.model == chipModel_GC700)
+               gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
++      /* These models/revisions don't have the 2D pipe bit */
++      if ((gpu->identity.model == chipModel_GC500 &&
++           gpu->identity.revision <= 2) ||
++          gpu->identity.model == chipModel_GC300)
++              gpu->identity.features |= chipFeatures_PIPE_2D;
++
+       if ((gpu->identity.model == chipModel_GC500 &&
+            gpu->identity.revision < 2) ||
+           (gpu->identity.model == chipModel_GC300 &&
+@@ -441,8 +447,9 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
+                               gpu_read(gpu, VIVS_HI_CHIP_MINOR_FEATURE_5);
+       }
+-      /* GC600 idle register reports zero bits where modules aren't present */
+-      if (gpu->identity.model == chipModel_GC600)
++      /* GC600/300 idle register reports zero bits where modules aren't present */
++      if (gpu->identity.model == chipModel_GC600 ||
++          gpu->identity.model == chipModel_GC300)
+               gpu->idle_mask = VIVS_HI_IDLE_STATE_TX |
+                                VIVS_HI_IDLE_STATE_RA |
+                                VIVS_HI_IDLE_STATE_SE |
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-fourcc-add-packed-10bit-yuv-4-2-0-format.patch b/queue-5.10/drm-fourcc-add-packed-10bit-yuv-4-2-0-format.patch
new file mode 100644 (file)
index 0000000..b04270a
--- /dev/null
@@ -0,0 +1,71 @@
+From 2342a7fb3e6adc8cf712a13a283b5bd93a58fb99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Dec 2021 10:17:37 +0100
+Subject: drm/fourcc: Add packed 10bit YUV 4:2:0 format
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 006ea1b5822f9019bd722ffc6242bc0880879e3d ]
+
+Adds a format that is 3 10bit YUV 4:2:0 samples packed into
+a 32bit word (with 2 spare bits).
+
+Supported on Broadcom BCM2711 chips.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://lore.kernel.org/r/20211215091739.135042-2-maxime@cerno.tech
+Stable-dep-of: b230555f3257 ("drm/fourcc: Fix vsub/hsub for Q410 and Q401")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_fourcc.c  |  3 +++
+ include/uapi/drm/drm_fourcc.h | 11 +++++++++++
+ 2 files changed, 14 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
+index 722c7ebe4e88..4d4b65a88bd1 100644
+--- a/drivers/gpu/drm/drm_fourcc.c
++++ b/drivers/gpu/drm/drm_fourcc.c
+@@ -286,6 +286,9 @@ const struct drm_format_info *__drm_format_info(u32 format)
+                 .num_planes = 3, .char_per_block = { 2, 2, 2 },
+                 .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
+                 .vsub = 0, .is_yuv = true },
++              { .format = DRM_FORMAT_P030,            .depth = 0,  .num_planes = 2,
++                .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 },
++                .hsub = 2, .vsub = 2, .is_yuv = true},
+       };
+       unsigned int i;
+diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
+index 5498d7a6556a..dad9d3b4a97a 100644
+--- a/include/uapi/drm/drm_fourcc.h
++++ b/include/uapi/drm/drm_fourcc.h
+@@ -271,6 +271,13 @@ extern "C" {
+  */
+ #define DRM_FORMAT_P016               fourcc_code('P', '0', '1', '6') /* 2x2 subsampled Cr:Cb plane 16 bits per channel */
++/* 2 plane YCbCr420.
++ * 3 10 bit components and 2 padding bits packed into 4 bytes.
++ * index 0 = Y plane, [31:0] x:Y2:Y1:Y0 2:10:10:10 little endian
++ * index 1 = Cr:Cb plane, [63:0] x:Cr2:Cb2:Cr1:x:Cb1:Cr0:Cb0 [2:10:10:10:2:10:10:10] little endian
++ */
++#define DRM_FORMAT_P030               fourcc_code('P', '0', '3', '0') /* 2x2 subsampled Cr:Cb plane 10 bits per channel packed */
++
+ /* 3 plane non-subsampled (444) YCbCr
+  * 16 bits per component, but only 10 bits are used and 6 bits are padded
+  * index 0: Y plane, [15:0] Y:x [10:6] little endian
+@@ -777,6 +784,10 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
+  * and UV.  Some SAND-using hardware stores UV in a separate tiled
+  * image from Y to reduce the column height, which is not supported
+  * with these modifiers.
++ *
++ * The DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT modifier is also
++ * supported for DRM_FORMAT_P030 where the columns remain as 128 bytes
++ * wide, but as this is a 10 bpp format that translates to 96 pixels.
+  */
+ #define DRM_FORMAT_MOD_BROADCOM_SAND32_COL_HEIGHT(v) \
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-fourcc-fix-vsub-hsub-for-q410-and-q401.patch b/queue-5.10/drm-fourcc-fix-vsub-hsub-for-q410-and-q401.patch
new file mode 100644 (file)
index 0000000..7ad76d7
--- /dev/null
@@ -0,0 +1,48 @@
+From b0a39f74a8ce5e42e6972f03f2ffa11332b7d035 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Sep 2022 15:43:06 +0100
+Subject: drm/fourcc: Fix vsub/hsub for Q410 and Q401
+
+From: Brian Starkey <brian.starkey@arm.com>
+
+[ Upstream commit b230555f3257f197dd98641ef6ebaf778b52dd51 ]
+
+These formats are not subsampled, but that means hsub and vsub should be
+1, not 0.
+
+Fixes: 94b292b27734 ("drm: drm_fourcc: add NV15, Q410, Q401 YUV formats")
+Reported-by: George Kennedy <george.kennedy@oracle.com>
+Reported-by: butt3rflyh4ck <butterflyhuangxx@gmail.com>
+Signed-off-by: Brian Starkey <brian.starkey@arm.com>
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220913144306.17279-1-brian.starkey@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_fourcc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
+index 4d4b65a88bd1..92152c06b75b 100644
+--- a/drivers/gpu/drm/drm_fourcc.c
++++ b/drivers/gpu/drm/drm_fourcc.c
+@@ -280,12 +280,12 @@ const struct drm_format_info *__drm_format_info(u32 format)
+                 .vsub = 2, .is_yuv = true },
+               { .format = DRM_FORMAT_Q410,            .depth = 0,
+                 .num_planes = 3, .char_per_block = { 2, 2, 2 },
+-                .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
+-                .vsub = 0, .is_yuv = true },
++                .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1,
++                .vsub = 1, .is_yuv = true },
+               { .format = DRM_FORMAT_Q401,            .depth = 0,
+                 .num_planes = 3, .char_per_block = { 2, 2, 2 },
+-                .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
+-                .vsub = 0, .is_yuv = true },
++                .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1,
++                .vsub = 1, .is_yuv = true },
+               { .format = DRM_FORMAT_P030,            .depth = 0,  .num_planes = 2,
+                 .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 },
+                 .hsub = 2, .vsub = 2, .is_yuv = true},
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-fsl-dcu-fix-return-type-of-fsl_dcu_drm_connector.patch b/queue-5.10/drm-fsl-dcu-fix-return-type-of-fsl_dcu_drm_connector.patch
new file mode 100644 (file)
index 0000000..2e6317a
--- /dev/null
@@ -0,0 +1,57 @@
+From f9f609262cdfc062f2e83a082e52dd1d2d0f9eb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 08:42:15 -0700
+Subject: drm/fsl-dcu: Fix return type of fsl_dcu_drm_connector_mode_valid()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 96d845a67b7e406cfed7880a724c8ca6121e022e ]
+
+With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
+indirect call targets are validated against the expected function
+pointer prototype to make sure the call target is valid to help mitigate
+ROP attacks. If they are not identical, there is a failure at run time,
+which manifests as either a kernel panic or thread getting killed. A
+proposed warning in clang aims to catch these at compile time, which
+reveals:
+
+  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c:74:16: error: incompatible function pointer types initializing 'enum drm_mode_status (*)(struct drm_connector *, struct drm_display_mode *)' with an expression of type 'int (struct drm_connector *, struct drm_display_mode *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+          .mode_valid = fsl_dcu_drm_connector_mode_valid,
+                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  1 error generated.
+
+->mode_valid() in 'struct drm_connector_helper_funcs' expects a return
+type of 'enum drm_mode_status', not 'int'. Adjust the return type of
+fsl_dcu_drm_connector_mode_valid() to match the prototype's to resolve
+the warning and CFI failure.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1750
+Reported-by: Sami Tolvanen <samitolvanen@google.com>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20221102154215.78059-1-nathan@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+index 4d4a715b429d..2c2b92324a2e 100644
+--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+@@ -60,8 +60,9 @@ static int fsl_dcu_drm_connector_get_modes(struct drm_connector *connector)
+       return drm_panel_get_modes(fsl_connector->panel, connector);
+ }
+-static int fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector,
+-                                          struct drm_display_mode *mode)
++static enum drm_mode_status
++fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector,
++                               struct drm_display_mode *mode)
+ {
+       if (mode->hdisplay & 0xf)
+               return MODE_ERROR;
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-mediatek-modify-dpi-power-on-off-sequence.patch b/queue-5.10/drm-mediatek-modify-dpi-power-on-off-sequence.patch
new file mode 100644 (file)
index 0000000..b44e9c0
--- /dev/null
@@ -0,0 +1,66 @@
+From 844094640b3fbf18583ecd751a14f6c9cdb83f78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 18:00:59 +0800
+Subject: drm/mediatek: Modify dpi power on/off sequence.
+
+From: Xinlei Lee <xinlei.lee@mediatek.com>
+
+[ Upstream commit ff446c0f6290185cefafe3b376bb86063a3a9f6a ]
+
+Modify dpi power on/off sequence so that the first gpio operation will
+take effect.
+
+Fixes: 6bd4763fd532 ("drm/mediatek: set dpi pin mode to gpio low to avoid leakage current")
+Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
+index c1ae336df683..aa3d472c79d7 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
+@@ -367,9 +367,6 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
+       if (--dpi->refcount != 0)
+               return;
+-      if (dpi->pinctrl && dpi->pins_gpio)
+-              pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
+-
+       mtk_dpi_disable(dpi);
+       clk_disable_unprepare(dpi->pixel_clk);
+       clk_disable_unprepare(dpi->engine_clk);
+@@ -394,9 +391,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
+               goto err_pixel;
+       }
+-      if (dpi->pinctrl && dpi->pins_dpi)
+-              pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
+-
+       return 0;
+ err_pixel:
+@@ -525,12 +519,18 @@ static void mtk_dpi_bridge_disable(struct drm_bridge *bridge)
+       struct mtk_dpi *dpi = bridge_to_dpi(bridge);
+       mtk_dpi_power_off(dpi);
++
++      if (dpi->pinctrl && dpi->pins_gpio)
++              pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
+ }
+ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
+ {
+       struct mtk_dpi *dpi = bridge_to_dpi(bridge);
++      if (dpi->pinctrl && dpi->pins_dpi)
++              pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
++
+       mtk_dpi_power_on(dpi);
+       mtk_dpi_set_display_mode(dpi, &dpi->mode);
+       mtk_dpi_enable(dpi);
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-msm-hdmi-drop-unused-gpio-support.patch b/queue-5.10/drm-msm-hdmi-drop-unused-gpio-support.patch
new file mode 100644 (file)
index 0000000..146ede6
--- /dev/null
@@ -0,0 +1,278 @@
+From 4311ec238eeefc33d10299b65d12a24880b0cd54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 15:23:42 +0300
+Subject: drm/msm/hdmi: drop unused GPIO support
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 68e674b13b17ed41aac2763d12ece6deaae8df58 ]
+
+The HDMI driver has code to configure extra GPIOs, which predates
+pinctrl support. Nowadays all platforms should use pinctrl instead.
+Neither of upstreamed Qualcomm platforms uses these properties, so it's
+safe to drop them.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Patchwork: https://patchwork.freedesktop.org/patch/488858/
+Link: https://lore.kernel.org/r/20220609122350.3157529-7-dmitry.baryshkov@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Stable-dep-of: b964444b2b64 ("drm/msm/hdmi: use devres helper for runtime PM management")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/hdmi/hdmi.c     | 66 +++++++----------------------
+ drivers/gpu/drm/msm/hdmi/hdmi.h     | 13 +-----
+ drivers/gpu/drm/msm/hdmi/hdmi_hpd.c | 62 ++-------------------------
+ 3 files changed, 21 insertions(+), 120 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
+index f6b09e8eca67..efb14043a6ec 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
+@@ -247,6 +247,20 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev)
+               hdmi->pwr_clks[i] = clk;
+       }
++      hdmi->hpd_gpiod = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN);
++      /* This will catch e.g. -EPROBE_DEFER */
++      if (IS_ERR(hdmi->hpd_gpiod)) {
++              ret = PTR_ERR(hdmi->hpd_gpiod);
++              DRM_DEV_ERROR(&pdev->dev, "failed to get hpd gpio: (%d)\n", ret);
++              goto fail;
++      }
++
++      if (!hdmi->hpd_gpiod)
++              DBG("failed to get HPD gpio");
++
++      if (hdmi->hpd_gpiod)
++              gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD");
++
+       pm_runtime_enable(&pdev->dev);
+       hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
+@@ -429,20 +443,6 @@ static struct hdmi_platform_config hdmi_tx_8996_config = {
+               .hpd_freq      = hpd_clk_freq_8x74,
+ };
+-static const struct {
+-      const char *name;
+-      const bool output;
+-      const int value;
+-      const char *label;
+-} msm_hdmi_gpio_pdata[] = {
+-      { "qcom,hdmi-tx-ddc-clk", true, 1, "HDMI_DDC_CLK" },
+-      { "qcom,hdmi-tx-ddc-data", true, 1, "HDMI_DDC_DATA" },
+-      { "qcom,hdmi-tx-hpd", false, 1, "HDMI_HPD" },
+-      { "qcom,hdmi-tx-mux-en", true, 1, "HDMI_MUX_EN" },
+-      { "qcom,hdmi-tx-mux-sel", true, 0, "HDMI_MUX_SEL" },
+-      { "qcom,hdmi-tx-mux-lpm", true, 1, "HDMI_MUX_LPM" },
+-};
+-
+ /*
+  * HDMI audio codec callbacks
+  */
+@@ -555,7 +555,7 @@ static int msm_hdmi_bind(struct device *dev, struct device *master, void *data)
+       struct hdmi_platform_config *hdmi_cfg;
+       struct hdmi *hdmi;
+       struct device_node *of_node = dev->of_node;
+-      int i, err;
++      int err;
+       hdmi_cfg = (struct hdmi_platform_config *)
+                       of_device_get_match_data(dev);
+@@ -567,42 +567,6 @@ static int msm_hdmi_bind(struct device *dev, struct device *master, void *data)
+       hdmi_cfg->mmio_name     = "core_physical";
+       hdmi_cfg->qfprom_mmio_name = "qfprom_physical";
+-      for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) {
+-              const char *name = msm_hdmi_gpio_pdata[i].name;
+-              struct gpio_desc *gpiod;
+-
+-              /*
+-               * We are fetching the GPIO lines "as is" since the connector
+-               * code is enabling and disabling the lines. Until that point
+-               * the power-on default value will be kept.
+-               */
+-              gpiod = devm_gpiod_get_optional(dev, name, GPIOD_ASIS);
+-              /* This will catch e.g. -PROBE_DEFER */
+-              if (IS_ERR(gpiod))
+-                      return PTR_ERR(gpiod);
+-              if (!gpiod) {
+-                      /* Try a second time, stripping down the name */
+-                      char name3[32];
+-
+-                      /*
+-                       * Try again after stripping out the "qcom,hdmi-tx"
+-                       * prefix. This is mainly to match "hpd-gpios" used
+-                       * in the upstream bindings.
+-                       */
+-                      if (sscanf(name, "qcom,hdmi-tx-%s", name3))
+-                              gpiod = devm_gpiod_get_optional(dev, name3, GPIOD_ASIS);
+-                      if (IS_ERR(gpiod))
+-                              return PTR_ERR(gpiod);
+-                      if (!gpiod)
+-                              DBG("failed to get gpio: %s", name);
+-              }
+-              hdmi_cfg->gpios[i].gpiod = gpiod;
+-              if (gpiod)
+-                      gpiod_set_consumer_name(gpiod, msm_hdmi_gpio_pdata[i].label);
+-              hdmi_cfg->gpios[i].output = msm_hdmi_gpio_pdata[i].output;
+-              hdmi_cfg->gpios[i].value = msm_hdmi_gpio_pdata[i].value;
+-      }
+-
+       dev->platform_data = hdmi_cfg;
+       hdmi = msm_hdmi_init(to_platform_device(dev));
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
+index 8d2706bec3b9..20f554312b17 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
+@@ -19,17 +19,9 @@
+ #include "msm_drv.h"
+ #include "hdmi.xml.h"
+-#define HDMI_MAX_NUM_GPIO     6
+-
+ struct hdmi_phy;
+ struct hdmi_platform_config;
+-struct hdmi_gpio_data {
+-      struct gpio_desc *gpiod;
+-      bool output;
+-      int value;
+-};
+-
+ struct hdmi_audio {
+       bool enabled;
+       struct hdmi_audio_infoframe infoframe;
+@@ -61,6 +53,8 @@ struct hdmi {
+       struct clk **hpd_clks;
+       struct clk **pwr_clks;
++      struct gpio_desc *hpd_gpiod;
++
+       struct hdmi_phy *phy;
+       struct device *phy_dev;
+@@ -109,9 +103,6 @@ struct hdmi_platform_config {
+       /* clks that need to be on for screen pwr (ie pixel clk): */
+       const char **pwr_clk_names;
+       int pwr_clk_cnt;
+-
+-      /* gpio's: */
+-      struct hdmi_gpio_data gpios[HDMI_MAX_NUM_GPIO];
+ };
+ struct hdmi_bridge {
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
+index c3a236bb952c..52ebe562ca9b 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
+@@ -60,48 +60,6 @@ static void msm_hdmi_phy_reset(struct hdmi *hdmi)
+       }
+ }
+-static int gpio_config(struct hdmi *hdmi, bool on)
+-{
+-      const struct hdmi_platform_config *config = hdmi->config;
+-      int i;
+-
+-      if (on) {
+-              for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) {
+-                      struct hdmi_gpio_data gpio = config->gpios[i];
+-
+-                      if (gpio.gpiod) {
+-                              if (gpio.output) {
+-                                      gpiod_direction_output(gpio.gpiod,
+-                                                             gpio.value);
+-                              } else {
+-                                      gpiod_direction_input(gpio.gpiod);
+-                                      gpiod_set_value_cansleep(gpio.gpiod,
+-                                                               gpio.value);
+-                              }
+-                      }
+-              }
+-
+-              DBG("gpio on");
+-      } else {
+-              for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) {
+-                      struct hdmi_gpio_data gpio = config->gpios[i];
+-
+-                      if (!gpio.gpiod)
+-                              continue;
+-
+-                      if (gpio.output) {
+-                              int value = gpio.value ? 0 : 1;
+-
+-                              gpiod_set_value_cansleep(gpio.gpiod, value);
+-                      }
+-              }
+-
+-              DBG("gpio off");
+-      }
+-
+-      return 0;
+-}
+-
+ static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
+ {
+       const struct hdmi_platform_config *config = hdmi->config;
+@@ -157,11 +115,8 @@ int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
+               goto fail;
+       }
+-      ret = gpio_config(hdmi, true);
+-      if (ret) {
+-              DRM_DEV_ERROR(dev, "failed to configure GPIOs: %d\n", ret);
+-              goto fail;
+-      }
++      if (hdmi->hpd_gpiod)
++              gpiod_set_value_cansleep(hdmi->hpd_gpiod, 1);
+       pm_runtime_get_sync(dev);
+       enable_hpd_clocks(hdmi, true);
+@@ -210,10 +165,6 @@ void msm_hdmi_hpd_disable(struct hdmi_bridge *hdmi_bridge)
+       enable_hpd_clocks(hdmi, false);
+       pm_runtime_put_autosuspend(dev);
+-      ret = gpio_config(hdmi, false);
+-      if (ret)
+-              dev_warn(dev, "failed to unconfigure GPIOs: %d\n", ret);
+-
+       ret = pinctrl_pm_select_sleep_state(dev);
+       if (ret)
+               dev_warn(dev, "pinctrl state chg failed: %d\n", ret);
+@@ -275,10 +226,7 @@ static enum drm_connector_status detect_reg(struct hdmi *hdmi)
+ #define HPD_GPIO_INDEX        2
+ static enum drm_connector_status detect_gpio(struct hdmi *hdmi)
+ {
+-      const struct hdmi_platform_config *config = hdmi->config;
+-      struct hdmi_gpio_data hpd_gpio = config->gpios[HPD_GPIO_INDEX];
+-
+-      return gpiod_get_value(hpd_gpio.gpiod) ?
++      return gpiod_get_value(hdmi->hpd_gpiod) ?
+                       connector_status_connected :
+                       connector_status_disconnected;
+ }
+@@ -288,8 +236,6 @@ enum drm_connector_status msm_hdmi_bridge_detect(
+ {
+       struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+       struct hdmi *hdmi = hdmi_bridge->hdmi;
+-      const struct hdmi_platform_config *config = hdmi->config;
+-      struct hdmi_gpio_data hpd_gpio = config->gpios[HPD_GPIO_INDEX];
+       enum drm_connector_status stat_gpio, stat_reg;
+       int retry = 20;
+@@ -297,7 +243,7 @@ enum drm_connector_status msm_hdmi_bridge_detect(
+        * some platforms may not have hpd gpio. Rely only on the status
+        * provided by REG_HDMI_HPD_INT_STATUS in this case.
+        */
+-      if (!hpd_gpio.gpiod)
++      if (!hdmi->hpd_gpiod)
+               return detect_reg(hdmi);
+       do {
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-msm-hdmi-switch-to-drm_bridge_connector.patch b/queue-5.10/drm-msm-hdmi-switch-to-drm_bridge_connector.patch
new file mode 100644 (file)
index 0000000..1566200
--- /dev/null
@@ -0,0 +1,466 @@
+From 85f60cb2fff229f542db38391bc587e7e66f7d39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Oct 2021 03:11:00 +0300
+Subject: drm/msm/hdmi: switch to drm_bridge_connector
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit caa24223463dfd75702a24daac13c93edb4aafac ]
+
+Merge old hdmi_bridge and hdmi_connector implementations. Use
+drm_bridge_connector instead.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Link: https://lore.kernel.org/r/20211015001100.4193241-2-dmitry.baryshkov@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Stable-dep-of: b964444b2b64 ("drm/msm/hdmi: use devres helper for runtime PM management")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/Makefile                  |   2 +-
+ drivers/gpu/drm/msm/hdmi/hdmi.c               |  12 +-
+ drivers/gpu/drm/msm/hdmi/hdmi.h               |  19 ++-
+ drivers/gpu/drm/msm/hdmi/hdmi_bridge.c        |  81 ++++++++-
+ .../msm/hdmi/{hdmi_connector.c => hdmi_hpd.c} | 154 ++----------------
+ 5 files changed, 109 insertions(+), 159 deletions(-)
+ rename drivers/gpu/drm/msm/hdmi/{hdmi_connector.c => hdmi_hpd.c} (63%)
+
+diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
+index 340682cd0f32..2457ef9851bb 100644
+--- a/drivers/gpu/drm/msm/Makefile
++++ b/drivers/gpu/drm/msm/Makefile
+@@ -19,7 +19,7 @@ msm-y := \
+       hdmi/hdmi.o \
+       hdmi/hdmi_audio.o \
+       hdmi/hdmi_bridge.o \
+-      hdmi/hdmi_connector.o \
++      hdmi/hdmi_hpd.o \
+       hdmi/hdmi_i2c.o \
+       hdmi/hdmi_phy.o \
+       hdmi/hdmi_phy_8960.o \
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
+index bd65dc9b8892..f6b09e8eca67 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
+@@ -8,6 +8,8 @@
+ #include <linux/of_irq.h>
+ #include <linux/of_gpio.h>
++#include <drm/drm_bridge_connector.h>
++
+ #include <sound/hdmi-codec.h>
+ #include "hdmi.h"
+@@ -41,7 +43,7 @@ static irqreturn_t msm_hdmi_irq(int irq, void *dev_id)
+       struct hdmi *hdmi = dev_id;
+       /* Process HPD: */
+-      msm_hdmi_connector_irq(hdmi->connector);
++      msm_hdmi_hpd_irq(hdmi->bridge);
+       /* Process DDC: */
+       msm_hdmi_i2c_irq(hdmi->i2c);
+@@ -311,7 +313,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
+               goto fail;
+       }
+-      hdmi->connector = msm_hdmi_connector_init(hdmi);
++      hdmi->connector = drm_bridge_connector_init(hdmi->dev, encoder);
+       if (IS_ERR(hdmi->connector)) {
+               ret = PTR_ERR(hdmi->connector);
+               DRM_DEV_ERROR(dev->dev, "failed to create HDMI connector: %d\n", ret);
+@@ -319,6 +321,8 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
+               goto fail;
+       }
++      drm_connector_attach_encoder(hdmi->connector, hdmi->encoder);
++
+       hdmi->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+       if (!hdmi->irq) {
+               ret = -EINVAL;
+@@ -335,7 +339,9 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
+               goto fail;
+       }
+-      ret = msm_hdmi_hpd_enable(hdmi->connector);
++      drm_bridge_connector_enable_hpd(hdmi->connector);
++
++      ret = msm_hdmi_hpd_enable(hdmi->bridge);
+       if (ret < 0) {
+               DRM_DEV_ERROR(&hdmi->pdev->dev, "failed to enable HPD: %d\n", ret);
+               goto fail;
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
+index d0b84f0abee1..8d2706bec3b9 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
+@@ -114,6 +114,13 @@ struct hdmi_platform_config {
+       struct hdmi_gpio_data gpios[HDMI_MAX_NUM_GPIO];
+ };
++struct hdmi_bridge {
++      struct drm_bridge base;
++      struct hdmi *hdmi;
++      struct work_struct hpd_work;
++};
++#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
++
+ void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on);
+ static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data)
+@@ -230,13 +237,11 @@ void msm_hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate);
+ struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi);
+ void msm_hdmi_bridge_destroy(struct drm_bridge *bridge);
+-/*
+- * hdmi connector:
+- */
+-
+-void msm_hdmi_connector_irq(struct drm_connector *connector);
+-struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi);
+-int msm_hdmi_hpd_enable(struct drm_connector *connector);
++void msm_hdmi_hpd_irq(struct drm_bridge *bridge);
++enum drm_connector_status msm_hdmi_bridge_detect(
++              struct drm_bridge *bridge);
++int msm_hdmi_hpd_enable(struct drm_bridge *bridge);
++void msm_hdmi_hpd_disable(struct hdmi_bridge *hdmi_bridge);
+ /*
+  * i2c adapter for ddc:
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+index 6e380db9287b..efcfdd70a02e 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+@@ -5,17 +5,16 @@
+  */
+ #include <linux/delay.h>
++#include <drm/drm_bridge_connector.h>
++#include "msm_kms.h"
+ #include "hdmi.h"
+-struct hdmi_bridge {
+-      struct drm_bridge base;
+-      struct hdmi *hdmi;
+-};
+-#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
+-
+ void msm_hdmi_bridge_destroy(struct drm_bridge *bridge)
+ {
++      struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
++
++      msm_hdmi_hpd_disable(hdmi_bridge);
+ }
+ static void msm_hdmi_power_on(struct drm_bridge *bridge)
+@@ -259,14 +258,76 @@ static void msm_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+               msm_hdmi_audio_update(hdmi);
+ }
++static struct edid *msm_hdmi_bridge_get_edid(struct drm_bridge *bridge,
++              struct drm_connector *connector)
++{
++      struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
++      struct hdmi *hdmi = hdmi_bridge->hdmi;
++      struct edid *edid;
++      uint32_t hdmi_ctrl;
++
++      hdmi_ctrl = hdmi_read(hdmi, REG_HDMI_CTRL);
++      hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl | HDMI_CTRL_ENABLE);
++
++      edid = drm_get_edid(connector, hdmi->i2c);
++
++      hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl);
++
++      hdmi->hdmi_mode = drm_detect_hdmi_monitor(edid);
++
++      return edid;
++}
++
++static enum drm_mode_status msm_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
++              const struct drm_display_info *info,
++              const struct drm_display_mode *mode)
++{
++      struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
++      struct hdmi *hdmi = hdmi_bridge->hdmi;
++      const struct hdmi_platform_config *config = hdmi->config;
++      struct msm_drm_private *priv = bridge->dev->dev_private;
++      struct msm_kms *kms = priv->kms;
++      long actual, requested;
++
++      requested = 1000 * mode->clock;
++      actual = kms->funcs->round_pixclk(kms,
++                      requested, hdmi_bridge->hdmi->encoder);
++
++      /* for mdp5/apq8074, we manage our own pixel clk (as opposed to
++       * mdp4/dtv stuff where pixel clk is assigned to mdp/encoder
++       * instead):
++       */
++      if (config->pwr_clk_cnt > 0)
++              actual = clk_round_rate(hdmi->pwr_clks[0], actual);
++
++      DBG("requested=%ld, actual=%ld", requested, actual);
++
++      if (actual != requested)
++              return MODE_CLOCK_RANGE;
++
++      return 0;
++}
++
+ static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = {
+               .pre_enable = msm_hdmi_bridge_pre_enable,
+               .enable = msm_hdmi_bridge_enable,
+               .disable = msm_hdmi_bridge_disable,
+               .post_disable = msm_hdmi_bridge_post_disable,
+               .mode_set = msm_hdmi_bridge_mode_set,
++              .mode_valid = msm_hdmi_bridge_mode_valid,
++              .get_edid = msm_hdmi_bridge_get_edid,
++              .detect = msm_hdmi_bridge_detect,
+ };
++static void
++msm_hdmi_hotplug_work(struct work_struct *work)
++{
++      struct hdmi_bridge *hdmi_bridge =
++              container_of(work, struct hdmi_bridge, hpd_work);
++      struct drm_bridge *bridge = &hdmi_bridge->base;
++
++      drm_bridge_hpd_notify(bridge, drm_bridge_detect(bridge));
++}
+ /* initialize bridge */
+ struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi)
+@@ -283,11 +344,17 @@ struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi)
+       }
+       hdmi_bridge->hdmi = hdmi;
++      INIT_WORK(&hdmi_bridge->hpd_work, msm_hdmi_hotplug_work);
+       bridge = &hdmi_bridge->base;
+       bridge->funcs = &msm_hdmi_bridge_funcs;
++      bridge->ddc = hdmi->i2c;
++      bridge->type = DRM_MODE_CONNECTOR_HDMIA;
++      bridge->ops = DRM_BRIDGE_OP_HPD |
++              DRM_BRIDGE_OP_DETECT |
++              DRM_BRIDGE_OP_EDID;
+-      ret = drm_bridge_attach(hdmi->encoder, bridge, NULL, 0);
++      ret = drm_bridge_attach(hdmi->encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+       if (ret)
+               goto fail;
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
+similarity index 63%
+rename from drivers/gpu/drm/msm/hdmi/hdmi_connector.c
+rename to drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
+index 58707a1f3878..c3a236bb952c 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
+@@ -11,13 +11,6 @@
+ #include "msm_kms.h"
+ #include "hdmi.h"
+-struct hdmi_connector {
+-      struct drm_connector base;
+-      struct hdmi *hdmi;
+-      struct work_struct hpd_work;
+-};
+-#define to_hdmi_connector(x) container_of(x, struct hdmi_connector, base)
+-
+ static void msm_hdmi_phy_reset(struct hdmi *hdmi)
+ {
+       unsigned int val;
+@@ -139,10 +132,10 @@ static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
+       }
+ }
+-int msm_hdmi_hpd_enable(struct drm_connector *connector)
++int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
+ {
+-      struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
+-      struct hdmi *hdmi = hdmi_connector->hdmi;
++      struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
++      struct hdmi *hdmi = hdmi_bridge->hdmi;
+       const struct hdmi_platform_config *config = hdmi->config;
+       struct device *dev = &hdmi->pdev->dev;
+       uint32_t hpd_ctrl;
+@@ -202,9 +195,9 @@ int msm_hdmi_hpd_enable(struct drm_connector *connector)
+       return ret;
+ }
+-static void hdp_disable(struct hdmi_connector *hdmi_connector)
++void msm_hdmi_hpd_disable(struct hdmi_bridge *hdmi_bridge)
+ {
+-      struct hdmi *hdmi = hdmi_connector->hdmi;
++      struct hdmi *hdmi = hdmi_bridge->hdmi;
+       const struct hdmi_platform_config *config = hdmi->config;
+       struct device *dev = &hdmi->pdev->dev;
+       int i, ret = 0;
+@@ -233,19 +226,10 @@ static void hdp_disable(struct hdmi_connector *hdmi_connector)
+       }
+ }
+-static void
+-msm_hdmi_hotplug_work(struct work_struct *work)
+-{
+-      struct hdmi_connector *hdmi_connector =
+-              container_of(work, struct hdmi_connector, hpd_work);
+-      struct drm_connector *connector = &hdmi_connector->base;
+-      drm_helper_hpd_irq_event(connector->dev);
+-}
+-
+-void msm_hdmi_connector_irq(struct drm_connector *connector)
++void msm_hdmi_hpd_irq(struct drm_bridge *bridge)
+ {
+-      struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
+-      struct hdmi *hdmi = hdmi_connector->hdmi;
++      struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
++      struct hdmi *hdmi = hdmi_bridge->hdmi;
+       uint32_t hpd_int_status, hpd_int_ctrl;
+       /* Process HPD: */
+@@ -268,7 +252,7 @@ void msm_hdmi_connector_irq(struct drm_connector *connector)
+                       hpd_int_ctrl |= HDMI_HPD_INT_CTRL_INT_CONNECT;
+               hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, hpd_int_ctrl);
+-              queue_work(hdmi->workq, &hdmi_connector->hpd_work);
++              queue_work(hdmi->workq, &hdmi_bridge->hpd_work);
+       }
+ }
+@@ -299,11 +283,11 @@ static enum drm_connector_status detect_gpio(struct hdmi *hdmi)
+                       connector_status_disconnected;
+ }
+-static enum drm_connector_status hdmi_connector_detect(
+-              struct drm_connector *connector, bool force)
++enum drm_connector_status msm_hdmi_bridge_detect(
++              struct drm_bridge *bridge)
+ {
+-      struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
+-      struct hdmi *hdmi = hdmi_connector->hdmi;
++      struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
++      struct hdmi *hdmi = hdmi_bridge->hdmi;
+       const struct hdmi_platform_config *config = hdmi->config;
+       struct hdmi_gpio_data hpd_gpio = config->gpios[HPD_GPIO_INDEX];
+       enum drm_connector_status stat_gpio, stat_reg;
+@@ -337,115 +321,3 @@ static enum drm_connector_status hdmi_connector_detect(
+       return stat_gpio;
+ }
+-
+-static void hdmi_connector_destroy(struct drm_connector *connector)
+-{
+-      struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
+-
+-      hdp_disable(hdmi_connector);
+-
+-      drm_connector_cleanup(connector);
+-
+-      kfree(hdmi_connector);
+-}
+-
+-static int msm_hdmi_connector_get_modes(struct drm_connector *connector)
+-{
+-      struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
+-      struct hdmi *hdmi = hdmi_connector->hdmi;
+-      struct edid *edid;
+-      uint32_t hdmi_ctrl;
+-      int ret = 0;
+-
+-      hdmi_ctrl = hdmi_read(hdmi, REG_HDMI_CTRL);
+-      hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl | HDMI_CTRL_ENABLE);
+-
+-      edid = drm_get_edid(connector, hdmi->i2c);
+-
+-      hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl);
+-
+-      hdmi->hdmi_mode = drm_detect_hdmi_monitor(edid);
+-      drm_connector_update_edid_property(connector, edid);
+-
+-      if (edid) {
+-              ret = drm_add_edid_modes(connector, edid);
+-              kfree(edid);
+-      }
+-
+-      return ret;
+-}
+-
+-static int msm_hdmi_connector_mode_valid(struct drm_connector *connector,
+-                               struct drm_display_mode *mode)
+-{
+-      struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
+-      struct hdmi *hdmi = hdmi_connector->hdmi;
+-      const struct hdmi_platform_config *config = hdmi->config;
+-      struct msm_drm_private *priv = connector->dev->dev_private;
+-      struct msm_kms *kms = priv->kms;
+-      long actual, requested;
+-
+-      requested = 1000 * mode->clock;
+-      actual = kms->funcs->round_pixclk(kms,
+-                      requested, hdmi_connector->hdmi->encoder);
+-
+-      /* for mdp5/apq8074, we manage our own pixel clk (as opposed to
+-       * mdp4/dtv stuff where pixel clk is assigned to mdp/encoder
+-       * instead):
+-       */
+-      if (config->pwr_clk_cnt > 0)
+-              actual = clk_round_rate(hdmi->pwr_clks[0], actual);
+-
+-      DBG("requested=%ld, actual=%ld", requested, actual);
+-
+-      if (actual != requested)
+-              return MODE_CLOCK_RANGE;
+-
+-      return 0;
+-}
+-
+-static const struct drm_connector_funcs hdmi_connector_funcs = {
+-      .detect = hdmi_connector_detect,
+-      .fill_modes = drm_helper_probe_single_connector_modes,
+-      .destroy = hdmi_connector_destroy,
+-      .reset = drm_atomic_helper_connector_reset,
+-      .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+-      .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+-};
+-
+-static const struct drm_connector_helper_funcs msm_hdmi_connector_helper_funcs = {
+-      .get_modes = msm_hdmi_connector_get_modes,
+-      .mode_valid = msm_hdmi_connector_mode_valid,
+-};
+-
+-/* initialize connector */
+-struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi)
+-{
+-      struct drm_connector *connector = NULL;
+-      struct hdmi_connector *hdmi_connector;
+-
+-      hdmi_connector = kzalloc(sizeof(*hdmi_connector), GFP_KERNEL);
+-      if (!hdmi_connector)
+-              return ERR_PTR(-ENOMEM);
+-
+-      hdmi_connector->hdmi = hdmi;
+-      INIT_WORK(&hdmi_connector->hpd_work, msm_hdmi_hotplug_work);
+-
+-      connector = &hdmi_connector->base;
+-
+-      drm_connector_init_with_ddc(hdmi->dev, connector,
+-                                  &hdmi_connector_funcs,
+-                                  DRM_MODE_CONNECTOR_HDMIA,
+-                                  hdmi->i2c);
+-      drm_connector_helper_add(connector, &msm_hdmi_connector_helper_funcs);
+-
+-      connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+-                      DRM_CONNECTOR_POLL_DISCONNECT;
+-
+-      connector->interlace_allowed = 0;
+-      connector->doublescan_allowed = 0;
+-
+-      drm_connector_attach_encoder(connector, hdmi->encoder);
+-
+-      return connector;
+-}
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-msm-use-drm_mode_copy.patch b/queue-5.10/drm-msm-use-drm_mode_copy.patch
new file mode 100644 (file)
index 0000000..6e4a848
--- /dev/null
@@ -0,0 +1,99 @@
+From 382a733c7dce26e0aa2e26717b55159069e6b578 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Nov 2022 21:25:42 +0200
+Subject: drm/msm: Use drm_mode_copy()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+[ Upstream commit b2a1c5ca50db22b3677676dd5bad5f6092429acf ]
+
+struct drm_display_mode embeds a list head, so overwriting
+the full struct with another one will corrupt the list
+(if the destination mode is on a list). Use drm_mode_copy()
+instead which explicitly preserves the list head of
+the destination mode.
+
+Even if we know the destination mode is not on any list
+using drm_mode_copy() seems decent as it sets a good
+example. Bad examples of not using it might eventually
+get copied into code where preserving the list head
+actually matters.
+
+Obviously one case not covered here is when the mode
+itself is embedded in a larger structure and the whole
+structure is copied. But if we are careful when copying
+into modes embedded in structures I think we can be a
+little more reassured that bogus list heads haven't been
+propagated in.
+
+@is_mode_copy@
+@@
+drm_mode_copy(...)
+{
+...
+}
+
+@depends on !is_mode_copy@
+struct drm_display_mode *mode;
+expression E, S;
+@@
+(
+- *mode = E
++ drm_mode_copy(mode, &E)
+|
+- memcpy(mode, E, S)
++ drm_mode_copy(mode, E)
+)
+
+@depends on !is_mode_copy@
+struct drm_display_mode mode;
+expression E;
+@@
+(
+- mode = E
++ drm_mode_copy(&mode, &E)
+|
+- memcpy(&mode, E, S)
++ drm_mode_copy(&mode, E)
+)
+
+@@
+struct drm_display_mode *mode;
+@@
+- &*mode
++ mode
+
+Cc: Rob Clark <robdclark@gmail.com>
+Cc: Sean Paul <sean@poorly.run>
+Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Cc: linux-arm-msm@vger.kernel.org
+Cc: freedreno@lists.freedesktop.org
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221107192545.9896-5-ville.syrjala@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dp/dp_display.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
+index 5a152d505dfb..1c3dcbc6cce8 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -848,7 +848,7 @@ static int dp_display_set_mode(struct msm_dp *dp_display,
+       dp = container_of(dp_display, struct dp_display_private, dp_display);
+-      dp->panel->dp_mode.drm_mode = mode->drm_mode;
++      drm_mode_copy(&dp->panel->dp_mode.drm_mode, &mode->drm_mode);
+       dp->panel->dp_mode.bpp = mode->bpp;
+       dp->panel->dp_mode.capabilities = mode->capabilities;
+       dp_panel_init_panel_info(dp->panel);
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-panel-panel-sitronix-st7701-remove-panel-on-dsi-.patch b/queue-5.10/drm-panel-panel-sitronix-st7701-remove-panel-on-dsi-.patch
new file mode 100644 (file)
index 0000000..e7d5a73
--- /dev/null
@@ -0,0 +1,45 @@
+From 3f05c4b90dcfd190045c34dbb0cbd4c01e9301eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Oct 2022 01:11:06 +0200
+Subject: drm/panel/panel-sitronix-st7701: Remove panel on DSI attach failure
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit c62102165dd79284d42383d2f7ed17301bd8e629 ]
+
+In case mipi_dsi_attach() fails, call drm_panel_remove() to
+avoid memory leak.
+
+Fixes: 849b2e3ff969 ("drm/panel: Add Sitronix ST7701 panel driver")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221014231106.468063-1-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-sitronix-st7701.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7701.c b/drivers/gpu/drm/panel/panel-sitronix-st7701.c
+index 4d2a149b202c..cd9f01940b17 100644
+--- a/drivers/gpu/drm/panel/panel-sitronix-st7701.c
++++ b/drivers/gpu/drm/panel/panel-sitronix-st7701.c
+@@ -384,7 +384,15 @@ static int st7701_dsi_probe(struct mipi_dsi_device *dsi)
+       st7701->dsi = dsi;
+       st7701->desc = desc;
+-      return mipi_dsi_attach(dsi);
++      ret = mipi_dsi_attach(dsi);
++      if (ret)
++              goto err_attach;
++
++      return 0;
++
++err_attach:
++      drm_panel_remove(&st7701->panel);
++      return ret;
+ }
+ static int st7701_dsi_remove(struct mipi_dsi_device *dsi)
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-radeon-add-the-missed-acpi_put_table-to-fix-memo.patch b/queue-5.10/drm-radeon-add-the-missed-acpi_put_table-to-fix-memo.patch
new file mode 100644 (file)
index 0000000..e8b1c6e
--- /dev/null
@@ -0,0 +1,86 @@
+From cba5ac78cf675adf2f247e37624859d547f160d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 17:50:02 +0800
+Subject: drm/radeon: Add the missed acpi_put_table() to fix memory leak
+
+From: Hanjun Guo <guohanjun@huawei.com>
+
+[ Upstream commit 10276a20be1115e1f76c189330da2992df980eee ]
+
+When the radeon driver reads the bios information from ACPI
+table in radeon_acpi_vfct_bios(), it misses to call acpi_put_table()
+to release the ACPI memory after the init, so add acpi_put_table()
+properly to fix the memory leak.
+
+v2: fix text formatting (Alex)
+
+Fixes: 268ba0a99f89 ("drm/radeon: implement ACPI VFCT vbios fetch (v3)")
+Signed-off-by: Hanjun Guo <guohanjun@huawei.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_bios.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
+index bb29cf02974d..34d2cb929c06 100644
+--- a/drivers/gpu/drm/radeon/radeon_bios.c
++++ b/drivers/gpu/drm/radeon/radeon_bios.c
+@@ -612,13 +612,14 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+       acpi_size tbl_size;
+       UEFI_ACPI_VFCT *vfct;
+       unsigned offset;
++      bool r = false;
+       if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+               return false;
+       tbl_size = hdr->length;
+       if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+               DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
+-              return false;
++              goto out;
+       }
+       vfct = (UEFI_ACPI_VFCT *)hdr;
+@@ -631,13 +632,13 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+               offset += sizeof(VFCT_IMAGE_HEADER);
+               if (offset > tbl_size) {
+                       DRM_ERROR("ACPI VFCT image header truncated\n");
+-                      return false;
++                      goto out;
+               }
+               offset += vhdr->ImageLength;
+               if (offset > tbl_size) {
+                       DRM_ERROR("ACPI VFCT image truncated\n");
+-                      return false;
++                      goto out;
+               }
+               if (vhdr->ImageLength &&
+@@ -649,15 +650,18 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+                       rdev->bios = kmemdup(&vbios->VbiosContent,
+                                            vhdr->ImageLength,
+                                            GFP_KERNEL);
++                      if (rdev->bios)
++                              r = true;
+-                      if (!rdev->bios)
+-                              return false;
+-                      return true;
++                      goto out;
+               }
+       }
+       DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
+-      return false;
++
++out:
++      acpi_put_table(hdr);
++      return r;
+ }
+ #else
+ static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-radeon-fix-pci-device-refcount-leak-in-radeon_at.patch b/queue-5.10/drm-radeon-fix-pci-device-refcount-leak-in-radeon_at.patch
new file mode 100644 (file)
index 0000000..1b368e1
--- /dev/null
@@ -0,0 +1,41 @@
+From 883b3cdba9660d62c4d4cefae4b72d9ab63f5a03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 19:30:42 +0800
+Subject: drm/radeon: Fix PCI device refcount leak in radeon_atrm_get_bios()
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit 725a521a18734f65de05b8d353b5bd0d3ca4c37a ]
+
+As comment of pci_get_class() says, it returns a pci_device with its
+refcount increased and decreased the refcount for the input parameter
+@from if it is not NULL.
+
+If we break the loop in radeon_atrm_get_bios() with 'pdev' not NULL, we
+need to call pci_dev_put() to decrease the refcount. Add the missing
+pci_dev_put() to avoid refcount leak.
+
+Fixes: d8ade3526b2a ("drm/radeon: handle non-VGA class pci devices with ATRM")
+Fixes: c61e2775873f ("drm/radeon: split ATRM support out from the ATPX handler (v3)")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_bios.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
+index 34d2cb929c06..0c94147f7625 100644
+--- a/drivers/gpu/drm/radeon/radeon_bios.c
++++ b/drivers/gpu/drm/radeon/radeon_bios.c
+@@ -227,6 +227,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
+       if (!found)
+               return false;
++      pci_dev_put(pdev);
+       rdev->bios = kmalloc(size, GFP_KERNEL);
+       if (!rdev->bios) {
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-rockchip-lvds-fix-pm-usage-counter-unbalance-in-.patch b/queue-5.10/drm-rockchip-lvds-fix-pm-usage-counter-unbalance-in-.patch
new file mode 100644 (file)
index 0000000..4849261
--- /dev/null
@@ -0,0 +1,63 @@
+From d6803e9db54d0e5009153d83e3b5af209f32da6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Sep 2022 21:21:07 +0800
+Subject: drm/rockchip: lvds: fix PM usage counter unbalance in poweron
+
+From: Zhang Qilong <zhangqilong3@huawei.com>
+
+[ Upstream commit 4dba27f1a14592ac4cf71c3bc1cc1fd05dea8015 ]
+
+pm_runtime_get_sync will increment pm usage counter even it failed.
+Forgetting to putting operation will result in reference leak here.
+We fix it by replacing it with the newest pm_runtime_resume_and_get
+to keep usage counter balanced.
+
+Fixes: 34cc0aa25456 ("drm/rockchip: Add support for Rockchip Soc LVDS")
+Fixes: cca1705c3d89 ("drm/rockchip: lvds: Add PX30 support")
+Signed-off-by: Zhang Qilong <zhangqilong3@huawei.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220922132107.105419-3-zhangqilong3@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_lvds.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+index 7c20b4a24a7e..e2487937c4e3 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
++++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+@@ -145,7 +145,7 @@ static int rk3288_lvds_poweron(struct rockchip_lvds *lvds)
+               DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret);
+               return ret;
+       }
+-      ret = pm_runtime_get_sync(lvds->dev);
++      ret = pm_runtime_resume_and_get(lvds->dev);
+       if (ret < 0) {
+               DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
+               clk_disable(lvds->pclk);
+@@ -329,16 +329,20 @@ static int px30_lvds_poweron(struct rockchip_lvds *lvds)
+ {
+       int ret;
+-      ret = pm_runtime_get_sync(lvds->dev);
++      ret = pm_runtime_resume_and_get(lvds->dev);
+       if (ret < 0) {
+               DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
+               return ret;
+       }
+       /* Enable LVDS mode */
+-      return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
++      ret = regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
+                                 PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1),
+                                 PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1));
++      if (ret)
++              pm_runtime_put(lvds->dev);
++
++      return ret;
+ }
+ static void px30_lvds_poweroff(struct rockchip_lvds *lvds)
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-rockchip-use-drm_mode_copy.patch b/queue-5.10/drm-rockchip-use-drm_mode_copy.patch
new file mode 100644 (file)
index 0000000..779db60
--- /dev/null
@@ -0,0 +1,124 @@
+From 56df0d79a1c61129131ac01f2b21d155509034a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Nov 2022 21:25:44 +0200
+Subject: drm/rockchip: Use drm_mode_copy()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+[ Upstream commit 2bfaa28000d2830d3209161a4541cce0660e1b84 ]
+
+struct drm_display_mode embeds a list head, so overwriting
+the full struct with another one will corrupt the list
+(if the destination mode is on a list). Use drm_mode_copy()
+instead which explicitly preserves the list head of
+the destination mode.
+
+Even if we know the destination mode is not on any list
+using drm_mode_copy() seems decent as it sets a good
+example. Bad examples of not using it might eventually
+get copied into code where preserving the list head
+actually matters.
+
+Obviously one case not covered here is when the mode
+itself is embedded in a larger structure and the whole
+structure is copied. But if we are careful when copying
+into modes embedded in structures I think we can be a
+little more reassured that bogus list heads haven't been
+propagated in.
+
+@is_mode_copy@
+@@
+drm_mode_copy(...)
+{
+...
+}
+
+@depends on !is_mode_copy@
+struct drm_display_mode *mode;
+expression E, S;
+@@
+(
+- *mode = E
++ drm_mode_copy(mode, &E)
+|
+- memcpy(mode, E, S)
++ drm_mode_copy(mode, E)
+)
+
+@depends on !is_mode_copy@
+struct drm_display_mode mode;
+expression E;
+@@
+(
+- mode = E
++ drm_mode_copy(&mode, &E)
+|
+- memcpy(&mode, E, S)
++ drm_mode_copy(&mode, E)
+)
+
+@@
+struct drm_display_mode *mode;
+@@
+- &*mode
++ mode
+
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Cc: Sandy Huang <hjc@rock-chips.com>
+Cc: "Heiko Stübner" <heiko@sntech.de>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: linux-rockchip@lists.infradead.org
+Link: https://patchwork.freedesktop.org/patch/msgid/20221107192545.9896-7-ville.syrjala@linux.intel.com
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +-
+ drivers/gpu/drm/rockchip/inno_hdmi.c   | 2 +-
+ drivers/gpu/drm/rockchip/rk3066_hdmi.c | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
+index 857c47c69ef1..adeaa0140f0f 100644
+--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
+@@ -564,7 +564,7 @@ static void cdn_dp_encoder_mode_set(struct drm_encoder *encoder,
+       video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
+       video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
+-      memcpy(&dp->mode, adjusted, sizeof(*mode));
++      drm_mode_copy(&dp->mode, adjusted);
+ }
+ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
+diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
+index 7afdc54eb3ec..78120da5e63a 100644
+--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
++++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
+@@ -488,7 +488,7 @@ static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+       inno_hdmi_setup(hdmi, adj_mode);
+       /* Store the display mode for plugin/DPMS poweron events */
+-      memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
++      drm_mode_copy(&hdmi->previous_mode, adj_mode);
+ }
+ static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
+diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+index 1c546c3a8998..17e7c40a9e7b 100644
+--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
++++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+@@ -383,7 +383,7 @@ rk3066_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+       struct rk3066_hdmi *hdmi = to_rk3066_hdmi(encoder);
+       /* Store the display mode for plugin/DPMS poweron events. */
+-      memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
++      drm_mode_copy(&hdmi->previous_mode, adj_mode);
+ }
+ static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder)
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-sti-fix-return-type-of-sti_-dvo-hda-hdmi-_connec.patch b/queue-5.10/drm-sti-fix-return-type-of-sti_-dvo-hda-hdmi-_connec.patch
new file mode 100644 (file)
index 0000000..ce4174c
--- /dev/null
@@ -0,0 +1,95 @@
+From 4993e3d41214c3a3df50edb73b9752f5613c4401 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 08:56:23 -0700
+Subject: drm/sti: Fix return type of sti_{dvo,hda,hdmi}_connector_mode_valid()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 0ad811cc08a937d875cbad0149c1bab17f84ba05 ]
+
+With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
+indirect call targets are validated against the expected function
+pointer prototype to make sure the call target is valid to help mitigate
+ROP attacks. If they are not identical, there is a failure at run time,
+which manifests as either a kernel panic or thread getting killed. A
+proposed warning in clang aims to catch these at compile time, which
+reveals:
+
+  drivers/gpu/drm/sti/sti_hda.c:637:16: error: incompatible function pointer types initializing 'enum drm_mode_status (*)(struct drm_connector *, struct drm_display_mode *)' with an expression of type 'int (struct drm_connector *, struct drm_display_mode *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+          .mode_valid = sti_hda_connector_mode_valid,
+                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  drivers/gpu/drm/sti/sti_dvo.c:376:16: error: incompatible function pointer types initializing 'enum drm_mode_status (*)(struct drm_connector *, struct drm_display_mode *)' with an expression of type 'int (struct drm_connector *, struct drm_display_mode *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+          .mode_valid = sti_dvo_connector_mode_valid,
+                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  drivers/gpu/drm/sti/sti_hdmi.c:1035:16: error: incompatible function pointer types initializing 'enum drm_mode_status (*)(struct drm_connector *, struct drm_display_mode *)' with an expression of type 'int (struct drm_connector *, struct drm_display_mode *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+          .mode_valid = sti_hdmi_connector_mode_valid,
+                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+->mode_valid() in 'struct drm_connector_helper_funcs' expects a return
+type of 'enum drm_mode_status', not 'int'. Adjust the return type of
+sti_{dvo,hda,hdmi}_connector_mode_valid() to match the prototype's to
+resolve the warning and CFI failure.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1750
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20221102155623.3042869-1-nathan@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/sti/sti_dvo.c  | 5 +++--
+ drivers/gpu/drm/sti/sti_hda.c  | 5 +++--
+ drivers/gpu/drm/sti/sti_hdmi.c | 5 +++--
+ 3 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
+index b0676a73a1d7..11225ac213e1 100644
+--- a/drivers/gpu/drm/sti/sti_dvo.c
++++ b/drivers/gpu/drm/sti/sti_dvo.c
+@@ -346,8 +346,9 @@ static int sti_dvo_connector_get_modes(struct drm_connector *connector)
+ #define CLK_TOLERANCE_HZ 50
+-static int sti_dvo_connector_mode_valid(struct drm_connector *connector,
+-                                      struct drm_display_mode *mode)
++static enum drm_mode_status
++sti_dvo_connector_mode_valid(struct drm_connector *connector,
++                           struct drm_display_mode *mode)
+ {
+       int target = mode->clock * 1000;
+       int target_min = target - CLK_TOLERANCE_HZ;
+diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
+index 84109800143a..418dfccc2faf 100644
+--- a/drivers/gpu/drm/sti/sti_hda.c
++++ b/drivers/gpu/drm/sti/sti_hda.c
+@@ -600,8 +600,9 @@ static int sti_hda_connector_get_modes(struct drm_connector *connector)
+ #define CLK_TOLERANCE_HZ 50
+-static int sti_hda_connector_mode_valid(struct drm_connector *connector,
+-                                      struct drm_display_mode *mode)
++static enum drm_mode_status
++sti_hda_connector_mode_valid(struct drm_connector *connector,
++                           struct drm_display_mode *mode)
+ {
+       int target = mode->clock * 1000;
+       int target_min = target - CLK_TOLERANCE_HZ;
+diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
+index 412664dfb0b0..1bcee73f5114 100644
+--- a/drivers/gpu/drm/sti/sti_hdmi.c
++++ b/drivers/gpu/drm/sti/sti_hdmi.c
+@@ -997,8 +997,9 @@ static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
+ #define CLK_TOLERANCE_HZ 50
+-static int sti_hdmi_connector_mode_valid(struct drm_connector *connector,
+-                                      struct drm_display_mode *mode)
++static enum drm_mode_status
++sti_hdmi_connector_mode_valid(struct drm_connector *connector,
++                            struct drm_display_mode *mode)
+ {
+       int target = mode->clock * 1000;
+       int target_min = target - CLK_TOLERANCE_HZ;
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-sti-use-drm_mode_copy.patch b/queue-5.10/drm-sti-use-drm_mode_copy.patch
new file mode 100644 (file)
index 0000000..3b18870
--- /dev/null
@@ -0,0 +1,121 @@
+From 00b0c482c4b3e3209ef7c15607b73c7d0f508a70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Nov 2022 21:25:45 +0200
+Subject: drm/sti: Use drm_mode_copy()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+[ Upstream commit 442cf8e22ba25a77cb9092d78733fdbac9844e50 ]
+
+struct drm_display_mode embeds a list head, so overwriting
+the full struct with another one will corrupt the list
+(if the destination mode is on a list). Use drm_mode_copy()
+instead which explicitly preserves the list head of
+the destination mode.
+
+Even if we know the destination mode is not on any list
+using drm_mode_copy() seems decent as it sets a good
+example. Bad examples of not using it might eventually
+get copied into code where preserving the list head
+actually matters.
+
+Obviously one case not covered here is when the mode
+itself is embedded in a larger structure and the whole
+structure is copied. But if we are careful when copying
+into modes embedded in structures I think we can be a
+little more reassured that bogus list heads haven't been
+propagated in.
+
+@is_mode_copy@
+@@
+drm_mode_copy(...)
+{
+...
+}
+
+@depends on !is_mode_copy@
+struct drm_display_mode *mode;
+expression E, S;
+@@
+(
+- *mode = E
++ drm_mode_copy(mode, &E)
+|
+- memcpy(mode, E, S)
++ drm_mode_copy(mode, E)
+)
+
+@depends on !is_mode_copy@
+struct drm_display_mode mode;
+expression E;
+@@
+(
+- mode = E
++ drm_mode_copy(&mode, &E)
+|
+- memcpy(&mode, E, S)
++ drm_mode_copy(&mode, E)
+)
+
+@@
+struct drm_display_mode *mode;
+@@
+- &*mode
++ mode
+
+Cc: Alain Volmat <alain.volmat@foss.st.com>
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221107192545.9896-8-ville.syrjala@linux.intel.com
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/sti/sti_dvo.c  | 2 +-
+ drivers/gpu/drm/sti/sti_hda.c  | 2 +-
+ drivers/gpu/drm/sti/sti_hdmi.c | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
+index ddb4184f0726..b0676a73a1d7 100644
+--- a/drivers/gpu/drm/sti/sti_dvo.c
++++ b/drivers/gpu/drm/sti/sti_dvo.c
+@@ -288,7 +288,7 @@ static void sti_dvo_set_mode(struct drm_bridge *bridge,
+       DRM_DEBUG_DRIVER("\n");
+-      memcpy(&dvo->mode, mode, sizeof(struct drm_display_mode));
++      drm_mode_copy(&dvo->mode, mode);
+       /* According to the path used (main or aux), the dvo clocks should
+        * have a different parent clock. */
+diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
+index 5c2b650b561d..84109800143a 100644
+--- a/drivers/gpu/drm/sti/sti_hda.c
++++ b/drivers/gpu/drm/sti/sti_hda.c
+@@ -523,7 +523,7 @@ static void sti_hda_set_mode(struct drm_bridge *bridge,
+       DRM_DEBUG_DRIVER("\n");
+-      memcpy(&hda->mode, mode, sizeof(struct drm_display_mode));
++      drm_mode_copy(&hda->mode, mode);
+       if (!hda_get_mode_idx(hda->mode, &mode_idx)) {
+               DRM_ERROR("Undefined mode\n");
+diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
+index 38a558768e53..412664dfb0b0 100644
+--- a/drivers/gpu/drm/sti/sti_hdmi.c
++++ b/drivers/gpu/drm/sti/sti_hdmi.c
+@@ -934,7 +934,7 @@ static void sti_hdmi_set_mode(struct drm_bridge *bridge,
+       DRM_DEBUG_DRIVER("\n");
+       /* Copy the drm display mode in the connector local structure */
+-      memcpy(&hdmi->mode, mode, sizeof(struct drm_display_mode));
++      drm_mode_copy(&hdmi->mode, mode);
+       /* Update clock framerate according to the selected mode */
+       ret = clk_set_rate(hdmi->clk_pix, mode->clock * 1000);
+-- 
+2.35.1
+
diff --git a/queue-5.10/drm-tegra-add-missing-clk_disable_unprepare-in-tegra.patch b/queue-5.10/drm-tegra-add-missing-clk_disable_unprepare-in-tegra.patch
new file mode 100644 (file)
index 0000000..d4c5089
--- /dev/null
@@ -0,0 +1,39 @@
+From 4d79bbe7cd9c2f7f665c502dabaf8cde208fe46d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 08:50:50 +0000
+Subject: drm/tegra: Add missing clk_disable_unprepare() in tegra_dc_probe()
+
+From: Zhang Zekun <zhangzekun11@huawei.com>
+
+[ Upstream commit 7ad4384d53c67672a8720cdc2ef638d7d1710ab8 ]
+
+Add the missing clk_disable_unprepare() before return from
+tegra_dc_probe() in the error handling path.
+
+Fixes: f68ba6912bd2 ("drm/tegra: dc: Link DC1 to DC0 on Tegra20")
+Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/dc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
+index ceb86338c003..958d12da902d 100644
+--- a/drivers/gpu/drm/tegra/dc.c
++++ b/drivers/gpu/drm/tegra/dc.c
+@@ -2564,8 +2564,10 @@ static int tegra_dc_probe(struct platform_device *pdev)
+       usleep_range(2000, 4000);
+       err = reset_control_assert(dc->rst);
+-      if (err < 0)
++      if (err < 0) {
++              clk_disable_unprepare(dc->clk);
+               return err;
++      }
+       usleep_range(2000, 4000);
+-- 
+2.35.1
+
diff --git a/queue-5.10/edac-i10nm-fix-refcount-leak-in-pci_get_dev_wrapper.patch b/queue-5.10/edac-i10nm-fix-refcount-leak-in-pci_get_dev_wrapper.patch
new file mode 100644 (file)
index 0000000..b03c317
--- /dev/null
@@ -0,0 +1,44 @@
+From 57ff9128014b51f30f07bfb028dec0ad938aeb6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 14:55:12 +0800
+Subject: EDAC/i10nm: fix refcount leak in pci_get_dev_wrapper()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 9c8921555907f4d723f01ed2d859b66f2d14f08e ]
+
+As the comment of pci_get_domain_bus_and_slot() says, it returns
+a PCI device with refcount incremented, so it doesn't need to
+call an extra pci_dev_get() in pci_get_dev_wrapper(), and the PCI
+device needs to be put in the error path.
+
+Fixes: d4dc89d069aa ("EDAC, i10nm: Add a driver for Intel 10nm server processors")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/r/20221128065512.3572550-1-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/i10nm_base.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c
+index 3a7362f968c9..43dbea6b6e30 100644
+--- a/drivers/edac/i10nm_base.c
++++ b/drivers/edac/i10nm_base.c
+@@ -53,11 +53,10 @@ static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus,
+       if (unlikely(pci_enable_device(pdev) < 0)) {
+               edac_dbg(2, "Failed to enable device %02x:%02x.%x\n",
+                        bus, dev, fun);
++              pci_dev_put(pdev);
+               return NULL;
+       }
+-      pci_dev_get(pdev);
+-
+       return pdev;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/ethernet-s2io-don-t-call-dev_kfree_skb-under-spin_lo.patch b/queue-5.10/ethernet-s2io-don-t-call-dev_kfree_skb-under-spin_lo.patch
new file mode 100644 (file)
index 0000000..0bf7355
--- /dev/null
@@ -0,0 +1,45 @@
+From 0ee7aa8eef9da708e640ae7f4a4b4cb3fb7b743a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 20:01:21 +0800
+Subject: ethernet: s2io: don't call dev_kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 6cee96e09df54ae17784c0f38a49e0ed8229b825 ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+It should use dev_kfree_skb_irq() or dev_consume_skb_irq() instead.
+The difference between them is free reason, dev_kfree_skb_irq() means
+the SKB is dropped in error and dev_consume_skb_irq() means the SKB
+is consumed in normal.
+
+In this case, dev_kfree_skb() is called in free_tx_buffers() to drop
+the SKBs in tx buffers, when the card is down, so replace it with
+dev_kfree_skb_irq() here.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/neterion/s2io.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
+index 8a30be698f99..ff46b08ac1f4 100644
+--- a/drivers/net/ethernet/neterion/s2io.c
++++ b/drivers/net/ethernet/neterion/s2io.c
+@@ -2384,7 +2384,7 @@ static void free_tx_buffers(struct s2io_nic *nic)
+                       skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
+                       if (skb) {
+                               swstats->mem_freed += skb->truesize;
+-                              dev_kfree_skb(skb);
++                              dev_kfree_skb_irq(skb);
+                               cnt++;
+                       }
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.10/ethtool-avoiding-integer-overflow-in-ethtool_phys_id.patch b/queue-5.10/ethtool-avoiding-integer-overflow-in-ethtool_phys_id.patch
new file mode 100644 (file)
index 0000000..14ae1a8
--- /dev/null
@@ -0,0 +1,43 @@
+From 8d18a7b45d21199806f7e95db61e8892d79ff866 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 15:29:01 +0300
+Subject: ethtool: avoiding integer overflow in ethtool_phys_id()
+
+From: Maxim Korotkov <korotkov.maxim.s@gmail.com>
+
+[ Upstream commit 64a8f8f7127da228d59a39e2c5e75f86590f90b4 ]
+
+The value of an arithmetic expression "n * id.data" is subject
+to possible overflow due to a failure to cast operands to a larger data
+type before performing arithmetic. Used macro for multiplication instead
+operator for avoiding overflow.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Signed-off-by: Maxim Korotkov <korotkov.maxim.s@gmail.com>
+Reviewed-by: Alexander Lobakin <alexandr.lobakin@intel.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/20221122122901.22294-1-korotkov.maxim.s@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 80d2a00d3097..47c2dd4a9b9f 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -1966,7 +1966,8 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
+       } else {
+               /* Driver expects to be called at twice the frequency in rc */
+               int n = rc * 2, interval = HZ / n;
+-              u64 count = n * id.data, i = 0;
++              u64 count = mul_u32_u32(n, id.data);
++              u64 i = 0;
+               do {
+                       rtnl_lock();
+-- 
+2.35.1
+
diff --git a/queue-5.10/eventfd-change-int-to-__u64-in-eventfd_signal-ifndef.patch b/queue-5.10/eventfd-change-int-to-__u64-in-eventfd_signal-ifndef.patch
new file mode 100644 (file)
index 0000000..450a329
--- /dev/null
@@ -0,0 +1,41 @@
+From 9e3a279df61f25cfd0035745a844194de4361769 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Nov 2022 22:01:54 +0800
+Subject: eventfd: change int to __u64 in eventfd_signal() ifndef
+ CONFIG_EVENTFD
+
+From: Zhang Qilong <zhangqilong3@huawei.com>
+
+[ Upstream commit fd4e60bf0ef8eb9edcfa12dda39e8b6ee9060492 ]
+
+Commit ee62c6b2dc93 ("eventfd: change int to __u64 in eventfd_signal()")
+forgot to change int to __u64 in the CONFIG_EVENTFD=n stub function.
+
+Link: https://lkml.kernel.org/r/20221124140154.104680-1-zhangqilong3@huawei.com
+Fixes: ee62c6b2dc93 ("eventfd: change int to __u64 in eventfd_signal()")
+Signed-off-by: Zhang Qilong <zhangqilong3@huawei.com>
+Cc: Dylan Yudaken <dylany@fb.com>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Sha Zhengju <handai.szj@taobao.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/eventfd.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h
+index dc4fd8a6644d..3482f9365a4d 100644
+--- a/include/linux/eventfd.h
++++ b/include/linux/eventfd.h
+@@ -61,7 +61,7 @@ static inline struct eventfd_ctx *eventfd_ctx_fdget(int fd)
+       return ERR_PTR(-ENOSYS);
+ }
+-static inline int eventfd_signal(struct eventfd_ctx *ctx, int n)
++static inline int eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
+ {
+       return -ENOSYS;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/f2fs-avoid-victim-selection-from-previous-victim-sec.patch b/queue-5.10/f2fs-avoid-victim-selection-from-previous-victim-sec.patch
new file mode 100644 (file)
index 0000000..5d79392
--- /dev/null
@@ -0,0 +1,48 @@
+From da90a60cef699e23103c1507d5e1ddf5e893097e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 18:03:20 +0900
+Subject: f2fs: avoid victim selection from previous victim section
+
+From: Yonggil Song <yonggil.song@samsung.com>
+
+[ Upstream commit e219aecfd4b766c4e878a3769057e9809f7fcadc ]
+
+When f2fs chooses GC victim in large section & LFS mode,
+next_victim_seg[gc_type] is referenced first. After segment is freed,
+next_victim_seg[gc_type] has the next segment number.
+However, next_victim_seg[gc_type] still has the last segment number
+even after the last segment of section is freed. In this case, when f2fs
+chooses a victim for the next GC round, the last segment of previous victim
+section is chosen as a victim.
+
+Initialize next_victim_seg[gc_type] to NULL_SEGNO for the last segment in
+large section.
+
+Fixes: e3080b0120a1 ("f2fs: support subsectional garbage collection")
+Signed-off-by: Yonggil Song <yonggil.song@samsung.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/gc.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 5ac0b605335f..89156568a4fb 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1649,8 +1649,9 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
+                               get_valid_blocks(sbi, segno, false) == 0)
+                       seg_freed++;
+-              if (__is_large_section(sbi) && segno + 1 < end_segno)
+-                      sbi->next_victim_seg[gc_type] = segno + 1;
++              if (__is_large_section(sbi))
++                      sbi->next_victim_seg[gc_type] =
++                              (segno + 1 < end_segno) ? segno + 1 : NULL_SEGNO;
+ skip:
+               f2fs_put_page(sum_page, 0);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/f2fs-fix-normal-discard-process.patch b/queue-5.10/f2fs-fix-normal-discard-process.patch
new file mode 100644 (file)
index 0000000..26d8260
--- /dev/null
@@ -0,0 +1,43 @@
+From f2a128e5faa1b291ec0635d7bec0dc1211e90bf6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Oct 2022 17:40:36 +0800
+Subject: f2fs: fix normal discard process
+
+From: Dongdong Zhang <zhangdongdong1@oppo.com>
+
+[ Upstream commit b5f1a218ae5e4339130d6e733f0e63d623e09a2c ]
+
+In the DPOLICY_BG mode, there is a conflict between
+the two conditions "i + 1 < dpolicy->granularity" and
+"i < DEFAULT_DISCARD_GRANULARITY". If i = 15, the first
+condition is false, it will enter the second condition
+and dispatch all small granularity discards in function
+ __issue_discard_cmd_orderly. The restrictive effect
+of the first condition to small discards will be
+invalidated. These two conditions should align.
+
+Fixes: 20ee4382322c ("f2fs: issue small discard by LBA order")
+Signed-off-by: Dongdong Zhang <zhangdongdong1@oppo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 68774d6198a5..7c90d93f4e43 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -1532,7 +1532,7 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
+               if (i + 1 < dpolicy->granularity)
+                       break;
+-              if (i < DEFAULT_DISCARD_GRANULARITY && dpolicy->ordered)
++              if (i + 1 < DEFAULT_DISCARD_GRANULARITY && dpolicy->ordered)
+                       return __issue_discard_cmd_orderly(sbi, dpolicy);
+               pend_list = &dcc->pend_list[i];
+-- 
+2.35.1
+
diff --git a/queue-5.10/f2fs-fix-the-race-condition-of-resize-flag-between-r.patch b/queue-5.10/f2fs-fix-the-race-condition-of-resize-flag-between-r.patch
new file mode 100644 (file)
index 0000000..ebec98f
--- /dev/null
@@ -0,0 +1,74 @@
+From 35d2709a2e1b80d0a8dc6323fe439f16ddcfcf57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 10:45:32 +0800
+Subject: f2fs: Fix the race condition of resize flag between resizefs
+
+From: Zhang Qilong <zhangqilong3@huawei.com>
+
+[ Upstream commit 28fc4e9077ce59ab28c89c20dc6be5154473218f ]
+
+Because the set/clear SBI_IS_RESIZEFS flag not between any locks,
+In the following case:
+  thread1                      thread2
+   ->ioctl(resizefs)
+    ->set RESIZEFS flag                 ->ioctl(resizefs)
+    ...                          ->set RESIZEFS flag
+    ->clear RESIZEFS flag
+                                 ->resizefs stream
+                                   # No RESIZEFS flag in the stream
+
+Also before freeze_super, the resizefs not started, we should not set
+the SBI_IS_RESIZEFS flag.
+
+So move the set/clear SBI_IS_RESIZEFS flag between the cp_mutex and
+gc_lock.
+
+Fixes: b4b10061ef98 ("f2fs: refactor resize_fs to avoid meta updates in progress")
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Signed-off-by: Zhang Qilong <zhangqilong3@huawei.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/gc.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 3baa62ef6e3a..5ac0b605335f 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -2035,8 +2035,6 @@ int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count)
+       if (err)
+               return err;
+-      set_sbi_flag(sbi, SBI_IS_RESIZEFS);
+-
+       freeze_super(sbi->sb);
+       down_write(&sbi->gc_lock);
+       mutex_lock(&sbi->cp_mutex);
+@@ -2052,6 +2050,7 @@ int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count)
+       if (err)
+               goto out_err;
++      set_sbi_flag(sbi, SBI_IS_RESIZEFS);
+       err = free_segment_range(sbi, secs, false);
+       if (err)
+               goto recover_out;
+@@ -2075,6 +2074,7 @@ int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count)
+               f2fs_commit_super(sbi, false);
+       }
+ recover_out:
++      clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
+       if (err) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_err(sbi, "resize_fs failed, should run fsck to repair!");
+@@ -2087,6 +2087,5 @@ int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count)
+       mutex_unlock(&sbi->cp_mutex);
+       up_write(&sbi->gc_lock);
+       thaw_super(sbi->sb);
+-      clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
+       return err;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/fbdev-pm2fb-fix-missing-pci_disable_device.patch b/queue-5.10/fbdev-pm2fb-fix-missing-pci_disable_device.patch
new file mode 100644 (file)
index 0000000..c39d8a8
--- /dev/null
@@ -0,0 +1,56 @@
+From 1e6a3c9ce131c2790bb4f8a979220b1c58751b1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Nov 2022 17:55:10 +0800
+Subject: fbdev: pm2fb: fix missing pci_disable_device()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit ed359a464846b48f76ea6cc5cd8257e545ac97f4 ]
+
+Add missing pci_disable_device() in error path of probe() and remove() path.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/pm2fb.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c
+index c12d46e28359..87b6a929a6b3 100644
+--- a/drivers/video/fbdev/pm2fb.c
++++ b/drivers/video/fbdev/pm2fb.c
+@@ -1529,8 +1529,10 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       }
+       info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev);
+-      if (!info)
+-              return -ENOMEM;
++      if (!info) {
++              err = -ENOMEM;
++              goto err_exit_disable;
++      }
+       default_par = info->par;
+       switch (pdev->device) {
+@@ -1711,6 +1713,8 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
+  err_exit_neither:
+       framebuffer_release(info);
++ err_exit_disable:
++      pci_disable_device(pdev);
+       return retval;
+ }
+@@ -1737,6 +1741,7 @@ static void pm2fb_remove(struct pci_dev *pdev)
+       fb_dealloc_cmap(&info->cmap);
+       kfree(info->pixmap.addr);
+       framebuffer_release(info);
++      pci_disable_device(pdev);
+ }
+ static const struct pci_device_id pm2fb_id_table[] = {
+-- 
+2.35.1
+
diff --git a/queue-5.10/fbdev-ssd1307fb-drop-optional-dependency.patch b/queue-5.10/fbdev-ssd1307fb-drop-optional-dependency.patch
new file mode 100644 (file)
index 0000000..7c7edf7
--- /dev/null
@@ -0,0 +1,38 @@
+From 252d5b9f294b060796c83f01b563733cb31bba04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 17:09:46 +0200
+Subject: fbdev: ssd1307fb: Drop optional dependency
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 025e3b507a3a8e1ee96a3112bb67495c77d6cdb6 ]
+
+Only a single out of three devices need a PWM, so from driver it's
+optional. Moreover it's a single driver in the entire kernel that
+currently selects PWM. Unfortunately this selection is a root cause
+of the circular dependencies when we want to enable optional PWM
+for some other drivers that select GPIOLIB.
+
+Fixes: a2ed00da5047 ("drivers/video: add support for the Solomon SSD1307 OLED Controller")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
+index 4f02db65dede..3ac78db17e46 100644
+--- a/drivers/video/fbdev/Kconfig
++++ b/drivers/video/fbdev/Kconfig
+@@ -2216,7 +2216,6 @@ config FB_SSD1307
+       select FB_SYS_COPYAREA
+       select FB_SYS_IMAGEBLIT
+       select FB_DEFERRED_IO
+-      select PWM
+       select FB_BACKLIGHT
+       help
+         This driver implements support for the Solomon SSD1307
+-- 
+2.35.1
+
diff --git a/queue-5.10/fbdev-uvesafb-fixes-an-error-handling-path-in-uvesaf.patch b/queue-5.10/fbdev-uvesafb-fixes-an-error-handling-path-in-uvesaf.patch
new file mode 100644 (file)
index 0000000..2dc7dc9
--- /dev/null
@@ -0,0 +1,39 @@
+From df7a9b60311382b883c20b284b4f8750d2d03856 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Dec 2022 12:35:22 +0100
+Subject: fbdev: uvesafb: Fixes an error handling path in uvesafb_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit a94371040712031ba129c7e9d8ff04a06a2f8207 ]
+
+If an error occurs after a successful uvesafb_init_mtrr() call, it must be
+undone by a corresponding arch_phys_wc_del() call, as already done in the
+remove function.
+
+This has been added in the remove function in commit 63e28a7a5ffc
+("uvesafb: Clean up MTRR code")
+
+Fixes: 8bdb3a2d7df4 ("uvesafb: the driver core")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/uvesafb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
+index def14ac0ebe1..661f12742e4f 100644
+--- a/drivers/video/fbdev/uvesafb.c
++++ b/drivers/video/fbdev/uvesafb.c
+@@ -1756,6 +1756,7 @@ static int uvesafb_probe(struct platform_device *dev)
+ out_unmap:
+       iounmap(info->screen_base);
+ out_mem:
++      arch_phys_wc_del(par->mtrr_handle);
+       release_mem_region(info->fix.smem_start, info->fix.smem_len);
+ out_reg:
+       release_region(0x3c0, 32);
+-- 
+2.35.1
+
diff --git a/queue-5.10/fbdev-vermilion-decrease-reference-count-in-error-pa.patch b/queue-5.10/fbdev-vermilion-decrease-reference-count-in-error-pa.patch
new file mode 100644 (file)
index 0000000..0432440
--- /dev/null
@@ -0,0 +1,40 @@
+From af2e1e3c25b10b794446c2c2f5666b5dd79a1232 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 16:56:54 +0800
+Subject: fbdev: vermilion: decrease reference count in error path
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit 001f2cdb952a9566c77fb4b5470cc361db5601bb ]
+
+pci_get_device() will increase the reference count for the returned
+pci_dev. For the error path, we need to use pci_dev_put() to decrease
+the reference count.
+
+Fixes: dbe7e429fedb ("vmlfb: framebuffer driver for Intel Vermilion Range")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/vermilion/vermilion.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c
+index ff61605b8764..a543643ce014 100644
+--- a/drivers/video/fbdev/vermilion/vermilion.c
++++ b/drivers/video/fbdev/vermilion/vermilion.c
+@@ -277,8 +277,10 @@ static int vmlfb_get_gpu(struct vml_par *par)
+       mutex_unlock(&vml_mutex);
+-      if (pci_enable_device(par->gpu) < 0)
++      if (pci_enable_device(par->gpu) < 0) {
++              pci_dev_put(par->gpu);
+               return -ENODEV;
++      }
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/fbdev-via-fix-error-in-via_core_init.patch b/queue-5.10/fbdev-via-fix-error-in-via_core_init.patch
new file mode 100644 (file)
index 0000000..167aac5
--- /dev/null
@@ -0,0 +1,47 @@
+From 3d922080545cd99d1941929bf1d36295462215db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 09:08:52 +0800
+Subject: fbdev: via: Fix error in via_core_init()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit 5886b130de953cfb8826f7771ec8640a79934a7f ]
+
+via_core_init() won't exit the driver when pci_register_driver() failed.
+Exit the viafb-i2c and the viafb-gpio in failed path to prevent error.
+
+VIA Graphics Integration Chipset framebuffer 2.4 initializing
+Error: Driver 'viafb-i2c' is already registered, aborting...
+Error: Driver 'viafb-gpio' is already registered, aborting...
+
+Fixes: 7582eb9be85f ("viafb: Turn GPIO and i2c into proper platform devices")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/via/via-core.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/via/via-core.c b/drivers/video/fbdev/via/via-core.c
+index 89d75079b730..0363b478fa3e 100644
+--- a/drivers/video/fbdev/via/via-core.c
++++ b/drivers/video/fbdev/via/via-core.c
+@@ -725,7 +725,14 @@ static int __init via_core_init(void)
+               return ret;
+       viafb_i2c_init();
+       viafb_gpio_init();
+-      return pci_register_driver(&via_driver);
++      ret = pci_register_driver(&via_driver);
++      if (ret) {
++              viafb_gpio_exit();
++              viafb_i2c_exit();
++              return ret;
++      }
++
++      return 0;
+ }
+ static void __exit via_core_exit(void)
+-- 
+2.35.1
+
diff --git a/queue-5.10/firmware-raspberrypi-fix-possible-memory-leak-in-rpi.patch b/queue-5.10/firmware-raspberrypi-fix-possible-memory-leak-in-rpi.patch
new file mode 100644 (file)
index 0000000..bed3a5b
--- /dev/null
@@ -0,0 +1,39 @@
+From 74888919387a819101bcc20a7784b96c7c63d0c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 15:06:36 +0800
+Subject: firmware: raspberrypi: fix possible memory leak in
+ rpi_firmware_probe()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 7b51161696e803fd5f9ad55b20a64c2df313f95c ]
+
+In rpi_firmware_probe(), if mbox_request_channel() fails, the 'fw' will
+not be freed through rpi_firmware_delete(), fix this leak by calling
+kfree() in the error path.
+
+Fixes: 1e7c57355a3b ("firmware: raspberrypi: Keep count of all consumers")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221117070636.3849773-1-yangyingliang@huawei.com
+Acked-by: Joel Savitz <jsavitz@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/raspberrypi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
+index 1d965c1252ca..9eef49da47e0 100644
+--- a/drivers/firmware/raspberrypi.c
++++ b/drivers/firmware/raspberrypi.c
+@@ -265,6 +265,7 @@ static int rpi_firmware_probe(struct platform_device *pdev)
+               int ret = PTR_ERR(fw->chan);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get mbox channel: %d\n", ret);
++              kfree(fw);
+               return ret;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/fs-don-t-audit-the-capability-check-in-simple_xattr_.patch b/queue-5.10/fs-don-t-audit-the-capability-check-in-simple_xattr_.patch
new file mode 100644 (file)
index 0000000..e7018ad
--- /dev/null
@@ -0,0 +1,54 @@
+From dac667cd40b298f870ed8913b93047168e35166f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Nov 2022 16:12:05 +0100
+Subject: fs: don't audit the capability check in simple_xattr_list()
+
+From: Ondrej Mosnacek <omosnace@redhat.com>
+
+[ Upstream commit e7eda157c4071cd1e69f4b1687b0fbe1ae5e6f46 ]
+
+The check being unconditional may lead to unwanted denials reported by
+LSMs when a process has the capability granted by DAC, but denied by an
+LSM. In the case of SELinux such denials are a problem, since they can't
+be effectively filtered out via the policy and when not silenced, they
+produce noise that may hide a true problem or an attack.
+
+Checking for the capability only if any trusted xattr is actually
+present wouldn't really address the issue, since calling listxattr(2) on
+such node on its own doesn't indicate an explicit attempt to see the
+trusted xattrs. Additionally, it could potentially leak the presence of
+trusted xattrs to an unprivileged user if they can check for the denials
+(e.g. through dmesg).
+
+Therefore, it's best (and simplest) to keep the check unconditional and
+instead use ns_capable_noaudit() that will silence any associated LSM
+denials.
+
+Fixes: 38f38657444d ("xattr: extract simple_xattr code from tmpfs")
+Reported-by: Martin Pitt <mpitt@redhat.com>
+Suggested-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Reviewed-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xattr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/xattr.c b/fs/xattr.c
+index cd7a563e8bcd..5a03eaadf029 100644
+--- a/fs/xattr.c
++++ b/fs/xattr.c
+@@ -1049,7 +1049,7 @@ static int xattr_list_one(char **buffer, ssize_t *remaining_size,
+ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
+                         char *buffer, size_t size)
+ {
+-      bool trusted = capable(CAP_SYS_ADMIN);
++      bool trusted = ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN);
+       struct simple_xattr *xattr;
+       ssize_t remaining_size = size;
+       int err = 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/fs-jfs-fix-shift-out-of-bounds-in-dballocag.patch b/queue-5.10/fs-jfs-fix-shift-out-of-bounds-in-dballocag.patch
new file mode 100644 (file)
index 0000000..1a45539
--- /dev/null
@@ -0,0 +1,90 @@
+From a382f52a7793f9e0a20d455f78e3045b83362902 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 08:48:07 -0500
+Subject: fs: jfs: fix shift-out-of-bounds in dbAllocAG
+
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+
+[ Upstream commit 898f706695682b9954f280d95e49fa86ffa55d08 ]
+
+Syzbot found a crash : UBSAN: shift-out-of-bounds in dbAllocAG. The
+underlying bug is the missing check of bmp->db_agl2size. The field can
+be greater than 64 and trigger the shift-out-of-bounds.
+
+Fix this bug by adding a check of bmp->db_agl2size in dbMount since this
+field is used in many following functions. The upper bound for this
+field is L2MAXL2SIZE - L2MAXAG, thanks for the help of Dave Kleikamp.
+Note that, for maintenance, I reorganized error handling code of dbMount.
+
+Reported-by: syzbot+15342c1aa6a00fb7a438@syzkaller.appspotmail.com
+Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_dmap.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
+index 0ce17ea8fa8a..b0a65aaed43e 100644
+--- a/fs/jfs/jfs_dmap.c
++++ b/fs/jfs/jfs_dmap.c
+@@ -155,7 +155,7 @@ int dbMount(struct inode *ipbmap)
+       struct bmap *bmp;
+       struct dbmap_disk *dbmp_le;
+       struct metapage *mp;
+-      int i;
++      int i, err;
+       /*
+        * allocate/initialize the in-memory bmap descriptor
+@@ -170,8 +170,8 @@ int dbMount(struct inode *ipbmap)
+                          BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage,
+                          PSIZE, 0);
+       if (mp == NULL) {
+-              kfree(bmp);
+-              return -EIO;
++              err = -EIO;
++              goto err_kfree_bmp;
+       }
+       /* copy the on-disk bmap descriptor to its in-memory version. */
+@@ -181,9 +181,8 @@ int dbMount(struct inode *ipbmap)
+       bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
+       bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
+       if (!bmp->db_numag) {
+-              release_metapage(mp);
+-              kfree(bmp);
+-              return -EINVAL;
++              err = -EINVAL;
++              goto err_release_metapage;
+       }
+       bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
+@@ -194,6 +193,11 @@ int dbMount(struct inode *ipbmap)
+       bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
+       bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
+       bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
++      if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) {
++              err = -EINVAL;
++              goto err_release_metapage;
++      }
++
+       for (i = 0; i < MAXAG; i++)
+               bmp->db_agfree[i] = le64_to_cpu(dbmp_le->dn_agfree[i]);
+       bmp->db_agsize = le64_to_cpu(dbmp_le->dn_agsize);
+@@ -214,6 +218,12 @@ int dbMount(struct inode *ipbmap)
+       BMAP_LOCK_INIT(bmp);
+       return (0);
++
++err_release_metapage:
++      release_metapage(mp);
++err_kfree_bmp:
++      kfree(bmp);
++      return err;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/fs-jfs-fix-shift-out-of-bounds-in-dbdiscardag.patch b/queue-5.10/fs-jfs-fix-shift-out-of-bounds-in-dbdiscardag.patch
new file mode 100644 (file)
index 0000000..9b70d93
--- /dev/null
@@ -0,0 +1,39 @@
+From 158487c4bfcc5711c9be4fca86f1021f0fe761ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Oct 2022 23:20:45 +0800
+Subject: fs: jfs: fix shift-out-of-bounds in dbDiscardAG
+
+From: Hoi Pok Wu <wuhoipok@gmail.com>
+
+[ Upstream commit 25e70c6162f207828dd405b432d8f2a98dbf7082 ]
+
+This should be applied to most URSAN bugs found recently by syzbot,
+by guarding the dbMount. As syzbot feeding rubbish into the bmap
+descriptor.
+
+Signed-off-by: Hoi Pok Wu <wuhoipok@gmail.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_dmap.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
+index b0a65aaed43e..2c9493011aec 100644
+--- a/fs/jfs/jfs_dmap.c
++++ b/fs/jfs/jfs_dmap.c
+@@ -198,6 +198,11 @@ int dbMount(struct inode *ipbmap)
+               goto err_release_metapage;
+       }
++      if (((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) {
++              err = -EINVAL;
++              goto err_release_metapage;
++      }
++
+       for (i = 0; i < MAXAG; i++)
+               bmp->db_agfree[i] = le64_to_cpu(dbmp_le->dn_agfree[i]);
+       bmp->db_agsize = le64_to_cpu(dbmp_le->dn_agsize);
+-- 
+2.35.1
+
diff --git a/queue-5.10/fs-sysv-fix-sysv_nblocks-returns-wrong-value.patch b/queue-5.10/fs-sysv-fix-sysv_nblocks-returns-wrong-value.patch
new file mode 100644 (file)
index 0000000..b0de95e
--- /dev/null
@@ -0,0 +1,42 @@
+From 45a58b9a9e2261a33ffe836da0161d4957197edf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 18:04:48 +0800
+Subject: fs: sysv: Fix sysv_nblocks() returns wrong value
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit e0c49bd2b4d3cd1751491eb2d940bce968ac65e9 ]
+
+sysv_nblocks() returns 'blocks' rather than 'res', which only counting
+the number of triple-indirect blocks and causing sysv_getattr() gets a
+wrong result.
+
+[AV: this is actually a sysv counterpart of minixfs fix -
+0fcd426de9d0 "[PATCH] minix block usage counting fix" in
+historical tree; mea culpa, should've thought to check
+fs/sysv back then...]
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/sysv/itree.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c
+index bcb67b0cabe7..31f66053e239 100644
+--- a/fs/sysv/itree.c
++++ b/fs/sysv/itree.c
+@@ -438,7 +438,7 @@ static unsigned sysv_nblocks(struct super_block *s, loff_t size)
+               res += blocks;
+               direct = 1;
+       }
+-      return blocks;
++      return res;
+ }
+ int sysv_getattr(const struct path *path, struct kstat *stat,
+-- 
+2.35.1
+
diff --git a/queue-5.10/futex-move-to-kernel-futex.patch b/queue-5.10/futex-move-to-kernel-futex.patch
new file mode 100644 (file)
index 0000000..18f5779
--- /dev/null
@@ -0,0 +1,85 @@
+From 9baf06cefe97f35d015ff06f2eaaa28ef9bb9316 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Sep 2021 14:10:50 -0300
+Subject: futex: Move to kernel/futex/
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit 77e52ae35463521041906c510fe580d15663bb93 ]
+
+In preparation for splitup..
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: André Almeida <andrealmeid@collabora.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: André Almeida <andrealmeid@collabora.com>
+Link: https://lore.kernel.org/r/20210923171111.300673-2-andrealmeid@collabora.com
+Stable-dep-of: 90d758896787 ("futex: Resend potentially swallowed owner death notification")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ MAINTAINERS                      | 2 +-
+ kernel/Makefile                  | 2 +-
+ kernel/futex/Makefile            | 3 +++
+ kernel/{futex.c => futex/core.c} | 2 +-
+ 4 files changed, 6 insertions(+), 3 deletions(-)
+ create mode 100644 kernel/futex/Makefile
+ rename kernel/{futex.c => futex/core.c} (99%)
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 4d10e79030a9..f6c6b403a1b7 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -7280,7 +7280,7 @@ F:       Documentation/locking/*futex*
+ F:    include/asm-generic/futex.h
+ F:    include/linux/futex.h
+ F:    include/uapi/linux/futex.h
+-F:    kernel/futex.c
++F:    kernel/futex/*
+ F:    tools/perf/bench/futex*
+ F:    tools/testing/selftests/futex/
+diff --git a/kernel/Makefile b/kernel/Makefile
+index e7905bdf6e97..82e9c843617f 100644
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -53,7 +53,7 @@ obj-$(CONFIG_FREEZER) += freezer.o
+ obj-$(CONFIG_PROFILING) += profile.o
+ obj-$(CONFIG_STACKTRACE) += stacktrace.o
+ obj-y += time/
+-obj-$(CONFIG_FUTEX) += futex.o
++obj-$(CONFIG_FUTEX) += futex/
+ obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
+ obj-$(CONFIG_SMP) += smp.o
+ ifneq ($(CONFIG_SMP),y)
+diff --git a/kernel/futex/Makefile b/kernel/futex/Makefile
+new file mode 100644
+index 000000000000..b89ba3fba343
+--- /dev/null
++++ b/kernel/futex/Makefile
+@@ -0,0 +1,3 @@
++# SPDX-License-Identifier: GPL-2.0
++
++obj-y += core.o
+diff --git a/kernel/futex.c b/kernel/futex/core.c
+similarity index 99%
+rename from kernel/futex.c
+rename to kernel/futex/core.c
+index 98a6e1b80bfe..26ca79c47480 100644
+--- a/kernel/futex.c
++++ b/kernel/futex/core.c
+@@ -42,7 +42,7 @@
+ #include <asm/futex.h>
+-#include "locking/rtmutex_common.h"
++#include "../locking/rtmutex_common.h"
+ /*
+  * READ this before attempting to hack on futexes!
+-- 
+2.35.1
+
diff --git a/queue-5.10/futex-resend-potentially-swallowed-owner-death-notif.patch b/queue-5.10/futex-resend-potentially-swallowed-owner-death-notif.patch
new file mode 100644 (file)
index 0000000..745f1ee
--- /dev/null
@@ -0,0 +1,105 @@
+From 2f6d7b2a0a2358b66df16f6e52c7a91facb93aa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Nov 2022 00:54:39 +0300
+Subject: futex: Resend potentially swallowed owner death notification
+
+From: Alexey Izbyshev <izbyshev@ispras.ru>
+
+[ Upstream commit 90d758896787048fa3d4209309d4800f3920e66f ]
+
+Commit ca16d5bee598 ("futex: Prevent robust futex exit race") addressed
+two cases when tasks waiting on a robust non-PI futex remained blocked
+despite the futex not being owned anymore:
+
+* if the owner died after writing zero to the futex word, but before
+  waking up a waiter
+
+* if a task waiting on the futex was woken up, but died before updating
+  the futex word (effectively swallowing the notification without acting
+  on it)
+
+In the second case, the task could be woken up either by the previous
+owner (after the futex word was reset to zero) or by the kernel (after
+the OWNER_DIED bit was set and the TID part of the futex word was reset
+to zero) if the previous owner died without the resetting the futex.
+
+Because the referenced commit wakes up a potential waiter only if the
+whole futex word is zero, the latter subcase remains unaddressed.
+
+Fix this by looking only at the TID part of the futex when deciding
+whether a wake up is needed.
+
+Fixes: ca16d5bee598 ("futex: Prevent robust futex exit race")
+Signed-off-by: Alexey Izbyshev <izbyshev@ispras.ru>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20221111215439.248185-1-izbyshev@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/futex/core.c | 28 ++++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+diff --git a/kernel/futex/core.c b/kernel/futex/core.c
+index 26ca79c47480..8dd0bc50ac36 100644
+--- a/kernel/futex/core.c
++++ b/kernel/futex/core.c
+@@ -3405,6 +3405,7 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr,
+                             bool pi, bool pending_op)
+ {
+       u32 uval, nval, mval;
++      pid_t owner;
+       int err;
+       /* Futex address must be 32bit aligned */
+@@ -3426,6 +3427,10 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr,
+        * 2. A woken up waiter is killed before it can acquire the
+        *    futex in user space.
+        *
++       * In the second case, the wake up notification could be generated
++       * by the unlock path in user space after setting the futex value
++       * to zero or by the kernel after setting the OWNER_DIED bit below.
++       *
+        * In both cases the TID validation below prevents a wakeup of
+        * potential waiters which can cause these waiters to block
+        * forever.
+@@ -3434,24 +3439,27 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr,
+        *
+        *      1) task->robust_list->list_op_pending != NULL
+        *         @pending_op == true
+-       *      2) User space futex value == 0
++       *      2) The owner part of user space futex value == 0
+        *      3) Regular futex: @pi == false
+        *
+        * If these conditions are met, it is safe to attempt waking up a
+        * potential waiter without touching the user space futex value and
+-       * trying to set the OWNER_DIED bit. The user space futex value is
+-       * uncontended and the rest of the user space mutex state is
+-       * consistent, so a woken waiter will just take over the
+-       * uncontended futex. Setting the OWNER_DIED bit would create
+-       * inconsistent state and malfunction of the user space owner died
+-       * handling.
+-       */
+-      if (pending_op && !pi && !uval) {
++       * trying to set the OWNER_DIED bit. If the futex value is zero,
++       * the rest of the user space mutex state is consistent, so a woken
++       * waiter will just take over the uncontended futex. Setting the
++       * OWNER_DIED bit would create inconsistent state and malfunction
++       * of the user space owner died handling. Otherwise, the OWNER_DIED
++       * bit is already set, and the woken waiter is expected to deal with
++       * this.
++       */
++      owner = uval & FUTEX_TID_MASK;
++
++      if (pending_op && !pi && !owner) {
+               futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY);
+               return 0;
+       }
+-      if ((uval & FUTEX_TID_MASK) != task_pid_vnr(curr))
++      if (owner != task_pid_vnr(curr))
+               return 0;
+       /*
+-- 
+2.35.1
+
diff --git a/queue-5.10/genirq-add-irqf_no_autoen-for-request_irq-nmi.patch b/queue-5.10/genirq-add-irqf_no_autoen-for-request_irq-nmi.patch
new file mode 100644 (file)
index 0000000..f7f0b5a
--- /dev/null
@@ -0,0 +1,107 @@
+From 238632ec9b3ae3daca6155bc92358be3c59b3d54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Mar 2021 11:49:15 +1300
+Subject: genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
+
+From: Barry Song <song.bao.hua@hisilicon.com>
+
+[ Upstream commit cbe16f35bee6880becca6f20d2ebf6b457148552 ]
+
+Many drivers don't want interrupts enabled automatically via request_irq().
+So they are handling this issue by either way of the below two:
+
+(1)
+  irq_set_status_flags(irq, IRQ_NOAUTOEN);
+  request_irq(dev, irq...);
+
+(2)
+  request_irq(dev, irq...);
+  disable_irq(irq);
+
+The code in the second way is silly and unsafe. In the small time gap
+between request_irq() and disable_irq(), interrupts can still come.
+
+The code in the first way is safe though it's subobtimal.
+
+Add a new IRQF_NO_AUTOEN flag which can be handed in by drivers to
+request_irq() and request_nmi(). It prevents the automatic enabling of the
+requested interrupt/nmi in the same safe way as #1 above. With that the
+various usage sites of #1 and #2 above can be simplified and corrected.
+
+Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: dmitry.torokhov@gmail.com
+Link: https://lore.kernel.org/r/20210302224916.13980-2-song.bao.hua@hisilicon.com
+Stable-dep-of: 99c05e4283a1 ("iio: adis: add '__adis_enable_irq()' implementation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/interrupt.h |  4 ++++
+ kernel/irq/manage.c       | 11 +++++++++--
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
+index ee8299eb1f52..0652b4858ba6 100644
+--- a/include/linux/interrupt.h
++++ b/include/linux/interrupt.h
+@@ -61,6 +61,9 @@
+  *                interrupt handler after suspending interrupts. For system
+  *                wakeup devices users need to implement wakeup detection in
+  *                their interrupt handlers.
++ * IRQF_NO_AUTOEN - Don't enable IRQ or NMI automatically when users request it.
++ *                Users will enable it explicitly by enable_irq() or enable_nmi()
++ *                later.
+  */
+ #define IRQF_SHARED           0x00000080
+ #define IRQF_PROBE_SHARED     0x00000100
+@@ -74,6 +77,7 @@
+ #define IRQF_NO_THREAD                0x00010000
+ #define IRQF_EARLY_RESUME     0x00020000
+ #define IRQF_COND_SUSPEND     0x00040000
++#define IRQF_NO_AUTOEN                0x00080000
+ #define IRQF_TIMER            (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
+diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
+index 3cb29835632f..437b073dc487 100644
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -1667,7 +1667,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
+                       irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
+               }
+-              if (irq_settings_can_autoenable(desc)) {
++              if (!(new->flags & IRQF_NO_AUTOEN) &&
++                  irq_settings_can_autoenable(desc)) {
+                       irq_startup(desc, IRQ_RESEND, IRQ_START_COND);
+               } else {
+                       /*
+@@ -2054,10 +2055,15 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
+        * which interrupt is which (messes up the interrupt freeing
+        * logic etc).
+        *
++       * Also shared interrupts do not go well with disabling auto enable.
++       * The sharing interrupt might request it while it's still disabled
++       * and then wait for interrupts forever.
++       *
+        * Also IRQF_COND_SUSPEND only makes sense for shared interrupts and
+        * it cannot be set along with IRQF_NO_SUSPEND.
+        */
+       if (((irqflags & IRQF_SHARED) && !dev_id) ||
++          ((irqflags & IRQF_SHARED) && (irqflags & IRQF_NO_AUTOEN)) ||
+           (!(irqflags & IRQF_SHARED) && (irqflags & IRQF_COND_SUSPEND)) ||
+           ((irqflags & IRQF_NO_SUSPEND) && (irqflags & IRQF_COND_SUSPEND)))
+               return -EINVAL;
+@@ -2213,7 +2219,8 @@ int request_nmi(unsigned int irq, irq_handler_t handler,
+       desc = irq_to_desc(irq);
+-      if (!desc || irq_settings_can_autoenable(desc) ||
++      if (!desc || (irq_settings_can_autoenable(desc) &&
++          !(irqflags & IRQF_NO_AUTOEN)) ||
+           !irq_settings_can_request(desc) ||
+           WARN_ON(irq_settings_is_per_cpu_devid(desc)) ||
+           !irq_supports_nmi(desc))
+-- 
+2.35.1
+
diff --git a/queue-5.10/genirq-irqdesc-don-t-try-to-remove-non-existing-sysf.patch b/queue-5.10/genirq-irqdesc-don-t-try-to-remove-non-existing-sysf.patch
new file mode 100644 (file)
index 0000000..175d612
--- /dev/null
@@ -0,0 +1,115 @@
+From 7cd82bcf0363301104766cb4d0e0fbab89d6202c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 23:16:12 +0800
+Subject: genirq/irqdesc: Don't try to remove non-existing sysfs files
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 9049e1ca41983ab773d7ea244bee86d7835ec9f5 ]
+
+Fault injection tests trigger warnings like this:
+
+  kernfs: can not remove 'chip_name', no directory
+  WARNING: CPU: 0 PID: 253 at fs/kernfs/dir.c:1616 kernfs_remove_by_name_ns+0xce/0xe0
+  RIP: 0010:kernfs_remove_by_name_ns+0xce/0xe0
+  Call Trace:
+   <TASK>
+   remove_files.isra.1+0x3f/0xb0
+   sysfs_remove_group+0x68/0xe0
+   sysfs_remove_groups+0x41/0x70
+   __kobject_del+0x45/0xc0
+   kobject_del+0x29/0x40
+   free_desc+0x42/0x70
+   irq_free_descs+0x5e/0x90
+
+The reason is that the interrupt descriptor sysfs handling does not roll
+back on a failing kobject_add() during allocation. If the descriptor is
+freed later on, kobject_del() is invoked with a not added kobject resulting
+in the above warnings.
+
+A proper rollback in case of a kobject_add() failure would be the straight
+forward solution. But this is not possible due to the way how interrupt
+descriptor sysfs handling works.
+
+Interrupt descriptors are allocated before sysfs becomes available. So the
+sysfs files for the early allocated descriptors are added later in the boot
+process. At this point there can be nothing useful done about a failing
+kobject_add(). For consistency the interrupt descriptor allocation always
+treats kobject_add() failures as non-critical and just emits a warning.
+
+To solve this problem, keep track in the interrupt descriptor whether
+kobject_add() was successful or not and make the invocation of
+kobject_del() conditional on that.
+
+[ tglx: Massage changelog, comments and use a state bit. ]
+
+Fixes: ecb3f394c5db ("genirq: Expose interrupt information through sysfs")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20221128151612.1786122-1-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/irq/internals.h |  2 ++
+ kernel/irq/irqdesc.c   | 15 +++++++++------
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
+index e58342ace11f..f1d83a8b4417 100644
+--- a/kernel/irq/internals.h
++++ b/kernel/irq/internals.h
+@@ -52,6 +52,7 @@ enum {
+  * IRQS_PENDING                       - irq is pending and replayed later
+  * IRQS_SUSPENDED             - irq is suspended
+  * IRQS_NMI                   - irq line is used to deliver NMIs
++ * IRQS_SYSFS                 - descriptor has been added to sysfs
+  */
+ enum {
+       IRQS_AUTODETECT         = 0x00000001,
+@@ -64,6 +65,7 @@ enum {
+       IRQS_SUSPENDED          = 0x00000800,
+       IRQS_TIMINGS            = 0x00001000,
+       IRQS_NMI                = 0x00002000,
++      IRQS_SYSFS              = 0x00004000,
+ };
+ #include "debug.h"
+diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
+index ca36c6179aa7..9b0914a063f9 100644
+--- a/kernel/irq/irqdesc.c
++++ b/kernel/irq/irqdesc.c
+@@ -288,22 +288,25 @@ static void irq_sysfs_add(int irq, struct irq_desc *desc)
+       if (irq_kobj_base) {
+               /*
+                * Continue even in case of failure as this is nothing
+-               * crucial.
++               * crucial and failures in the late irq_sysfs_init()
++               * cannot be rolled back.
+                */
+               if (kobject_add(&desc->kobj, irq_kobj_base, "%d", irq))
+                       pr_warn("Failed to add kobject for irq %d\n", irq);
++              else
++                      desc->istate |= IRQS_SYSFS;
+       }
+ }
+ static void irq_sysfs_del(struct irq_desc *desc)
+ {
+       /*
+-       * If irq_sysfs_init() has not yet been invoked (early boot), then
+-       * irq_kobj_base is NULL and the descriptor was never added.
+-       * kobject_del() complains about a object with no parent, so make
+-       * it conditional.
++       * Only invoke kobject_del() when kobject_add() was successfully
++       * invoked for the descriptor. This covers both early boot, where
++       * sysfs is not initialized yet, and the case of a failed
++       * kobject_add() invocation.
+        */
+-      if (irq_kobj_base)
++      if (desc->istate & IRQS_SYSFS)
+               kobject_del(&desc->kobj);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/gpiolib-cdev-fix-null-pointer-dereferences.patch b/queue-5.10/gpiolib-cdev-fix-null-pointer-dereferences.patch
new file mode 100644 (file)
index 0000000..6de273c
--- /dev/null
@@ -0,0 +1,134 @@
+From 28230baf5ee74b90e360c9f4ce370f18a91d22c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 13:39:02 +0100
+Subject: gpiolib: cdev: fix NULL-pointer dereferences
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit 533aae7c94dbc2b14301cfd68ae7e0e90f0c8438 ]
+
+There are several places where we can crash the kernel by requesting
+lines, unbinding the GPIO device, then calling any of the system calls
+relevant to the GPIO character device's annonymous file descriptors:
+ioctl(), read(), poll().
+
+While I observed it with the GPIO simulator, it will also happen for any
+of the GPIO devices that can be hot-unplugged - for instance any HID GPIO
+expander (e.g. CP2112).
+
+This affects both v1 and v2 uAPI.
+
+This fixes it partially by checking if gdev->chip is not NULL but it
+doesn't entirely remedy the situation as we still have a race condition
+in which another thread can remove the device after the check.
+
+Fixes: d7c51b47ac11 ("gpio: userspace ABI for reading/writing GPIO lines")
+Fixes: 3c0d9c635ae2 ("gpiolib: cdev: support GPIO_V2_GET_LINE_IOCTL and GPIO_V2_LINE_GET_VALUES_IOCTL")
+Fixes: aad955842d1c ("gpiolib: cdev: support GPIO_V2_GET_LINEINFO_IOCTL and GPIO_V2_GET_LINEINFO_WATCH_IOCTL")
+Fixes: a54756cb24ea ("gpiolib: cdev: support GPIO_V2_LINE_SET_CONFIG_IOCTL")
+Fixes: 7b8e00d98168 ("gpiolib: cdev: support GPIO_V2_LINE_SET_VALUES_IOCTL")
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib-cdev.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
+index b51b4d7a611e..40d0196d8bdc 100644
+--- a/drivers/gpio/gpiolib-cdev.c
++++ b/drivers/gpio/gpiolib-cdev.c
+@@ -200,6 +200,9 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
+       unsigned int i;
+       int ret;
++      if (!lh->gdev->chip)
++              return -ENODEV;
++
+       switch (cmd) {
+       case GPIOHANDLE_GET_LINE_VALUES_IOCTL:
+               /* NOTE: It's okay to read values of output lines */
+@@ -1165,6 +1168,9 @@ static long linereq_ioctl(struct file *file, unsigned int cmd,
+       struct linereq *lr = file->private_data;
+       void __user *ip = (void __user *)arg;
++      if (!lr->gdev->chip)
++              return -ENODEV;
++
+       switch (cmd) {
+       case GPIO_V2_LINE_GET_VALUES_IOCTL:
+               return linereq_get_values(lr, ip);
+@@ -1191,6 +1197,9 @@ static __poll_t linereq_poll(struct file *file,
+       struct linereq *lr = file->private_data;
+       __poll_t events = 0;
++      if (!lr->gdev->chip)
++              return EPOLLHUP | EPOLLERR;
++
+       poll_wait(file, &lr->wait, wait);
+       if (!kfifo_is_empty_spinlocked_noirqsave(&lr->events,
+@@ -1210,6 +1219,9 @@ static ssize_t linereq_read(struct file *file,
+       ssize_t bytes_read = 0;
+       int ret;
++      if (!lr->gdev->chip)
++              return -ENODEV;
++
+       if (count < sizeof(le))
+               return -EINVAL;
+@@ -1475,6 +1487,9 @@ static __poll_t lineevent_poll(struct file *file,
+       struct lineevent_state *le = file->private_data;
+       __poll_t events = 0;
++      if (!le->gdev->chip)
++              return EPOLLHUP | EPOLLERR;
++
+       poll_wait(file, &le->wait, wait);
+       if (!kfifo_is_empty_spinlocked_noirqsave(&le->events, &le->wait.lock))
+@@ -1510,6 +1525,9 @@ static ssize_t lineevent_read(struct file *file,
+       ssize_t ge_size;
+       int ret;
++      if (!le->gdev->chip)
++              return -ENODEV;
++
+       /*
+        * When compatible system call is being used the struct gpioevent_data,
+        * in case of at least ia32, has different size due to the alignment
+@@ -1588,6 +1606,9 @@ static long lineevent_ioctl(struct file *file, unsigned int cmd,
+       void __user *ip = (void __user *)arg;
+       struct gpiohandle_data ghd;
++      if (!le->gdev->chip)
++              return -ENODEV;
++
+       /*
+        * We can get the value for an event line but not set it,
+        * because it is input by definition.
+@@ -2168,6 +2189,9 @@ static __poll_t lineinfo_watch_poll(struct file *file,
+       struct gpio_chardev_data *cdev = file->private_data;
+       __poll_t events = 0;
++      if (!cdev->gdev->chip)
++              return EPOLLHUP | EPOLLERR;
++
+       poll_wait(file, &cdev->wait, pollt);
+       if (!kfifo_is_empty_spinlocked_noirqsave(&cdev->events,
+@@ -2186,6 +2210,9 @@ static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
+       int ret;
+       size_t event_size;
++      if (!cdev->gdev->chip)
++              return -ENODEV;
++
+ #ifndef CONFIG_GPIO_CDEV_V1
+       event_size = sizeof(struct gpio_v2_line_info_changed);
+       if (count < event_size)
+-- 
+2.35.1
+
diff --git a/queue-5.10/gpiolib-get-rid-of-redundant-else.patch b/queue-5.10/gpiolib-get-rid-of-redundant-else.patch
new file mode 100644 (file)
index 0000000..1ab17d1
--- /dev/null
@@ -0,0 +1,191 @@
+From 08bdd5101e375f12825eb87e2f2df20f6d71e34d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Mar 2022 18:06:20 +0300
+Subject: gpiolib: Get rid of redundant 'else'
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 1cef8b5019769d46725932eeace7a383bca97905 ]
+
+In the snippets like the following
+
+       if (...)
+               return / goto / break / continue ...;
+       else
+               ...
+
+the 'else' is redundant. Get rid of it. In case of IOCTLs use
+switch-case pattern that seems the usual in such cases.
+
+While at it, clarify necessity of else in gpiod_direction_output()
+by attaching else if to the closing curly brace on a previous line.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Stable-dep-of: 533aae7c94db ("gpiolib: cdev: fix NULL-pointer dereferences")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib-cdev.c | 66 ++++++++++++++++++++-----------------
+ drivers/gpio/gpiolib.c      | 12 +++----
+ 2 files changed, 40 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
+index 381cfa26a4a1..b51b4d7a611e 100644
+--- a/drivers/gpio/gpiolib-cdev.c
++++ b/drivers/gpio/gpiolib-cdev.c
+@@ -197,16 +197,15 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
+       void __user *ip = (void __user *)arg;
+       struct gpiohandle_data ghd;
+       DECLARE_BITMAP(vals, GPIOHANDLES_MAX);
+-      int i;
++      unsigned int i;
++      int ret;
+-      if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
+-              /* NOTE: It's ok to read values of output lines. */
+-              int ret = gpiod_get_array_value_complex(false,
+-                                                      true,
+-                                                      lh->num_descs,
+-                                                      lh->descs,
+-                                                      NULL,
+-                                                      vals);
++      switch (cmd) {
++      case GPIOHANDLE_GET_LINE_VALUES_IOCTL:
++              /* NOTE: It's okay to read values of output lines */
++              ret = gpiod_get_array_value_complex(false, true,
++                                                  lh->num_descs, lh->descs,
++                                                  NULL, vals);
+               if (ret)
+                       return ret;
+@@ -218,7 +217,7 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
+                       return -EFAULT;
+               return 0;
+-      } else if (cmd == GPIOHANDLE_SET_LINE_VALUES_IOCTL) {
++      case GPIOHANDLE_SET_LINE_VALUES_IOCTL:
+               /*
+                * All line descriptors were created at once with the same
+                * flags so just check if the first one is really output.
+@@ -240,10 +239,11 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
+                                                    lh->descs,
+                                                    NULL,
+                                                    vals);
+-      } else if (cmd == GPIOHANDLE_SET_CONFIG_IOCTL) {
++      case GPIOHANDLE_SET_CONFIG_IOCTL:
+               return linehandle_set_config(lh, ip);
++      default:
++              return -EINVAL;
+       }
+-      return -EINVAL;
+ }
+ #ifdef CONFIG_COMPAT
+@@ -1165,14 +1165,16 @@ static long linereq_ioctl(struct file *file, unsigned int cmd,
+       struct linereq *lr = file->private_data;
+       void __user *ip = (void __user *)arg;
+-      if (cmd == GPIO_V2_LINE_GET_VALUES_IOCTL)
++      switch (cmd) {
++      case GPIO_V2_LINE_GET_VALUES_IOCTL:
+               return linereq_get_values(lr, ip);
+-      else if (cmd == GPIO_V2_LINE_SET_VALUES_IOCTL)
++      case GPIO_V2_LINE_SET_VALUES_IOCTL:
+               return linereq_set_values(lr, ip);
+-      else if (cmd == GPIO_V2_LINE_SET_CONFIG_IOCTL)
++      case GPIO_V2_LINE_SET_CONFIG_IOCTL:
+               return linereq_set_config(lr, ip);
+-
+-      return -EINVAL;
++      default:
++              return -EINVAL;
++      }
+ }
+ #ifdef CONFIG_COMPAT
+@@ -2095,28 +2097,30 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+               return -ENODEV;
+       /* Fill in the struct and pass to userspace */
+-      if (cmd == GPIO_GET_CHIPINFO_IOCTL) {
++      switch (cmd) {
++      case GPIO_GET_CHIPINFO_IOCTL:
+               return chipinfo_get(cdev, ip);
+ #ifdef CONFIG_GPIO_CDEV_V1
+-      } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) {
++      case GPIO_GET_LINEHANDLE_IOCTL:
+               return linehandle_create(gdev, ip);
+-      } else if (cmd == GPIO_GET_LINEEVENT_IOCTL) {
++      case GPIO_GET_LINEEVENT_IOCTL:
+               return lineevent_create(gdev, ip);
+-      } else if (cmd == GPIO_GET_LINEINFO_IOCTL ||
+-                 cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) {
+-              return lineinfo_get_v1(cdev, ip,
+-                                     cmd == GPIO_GET_LINEINFO_WATCH_IOCTL);
++      case GPIO_GET_LINEINFO_IOCTL:
++              return lineinfo_get_v1(cdev, ip, false);
++      case GPIO_GET_LINEINFO_WATCH_IOCTL:
++              return lineinfo_get_v1(cdev, ip, true);
+ #endif /* CONFIG_GPIO_CDEV_V1 */
+-      } else if (cmd == GPIO_V2_GET_LINEINFO_IOCTL ||
+-                 cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL) {
+-              return lineinfo_get(cdev, ip,
+-                                  cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL);
+-      } else if (cmd == GPIO_V2_GET_LINE_IOCTL) {
++      case GPIO_V2_GET_LINEINFO_IOCTL:
++              return lineinfo_get(cdev, ip, false);
++      case GPIO_V2_GET_LINEINFO_WATCH_IOCTL:
++              return lineinfo_get(cdev, ip, true);
++      case GPIO_V2_GET_LINE_IOCTL:
+               return linereq_create(gdev, ip);
+-      } else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) {
++      case GPIO_GET_LINEINFO_UNWATCH_IOCTL:
+               return lineinfo_unwatch(cdev, ip);
++      default:
++              return -EINVAL;
+       }
+-      return -EINVAL;
+ }
+ #ifdef CONFIG_COMPAT
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index 59d8affad343..3e01a3ac652d 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -186,9 +186,8 @@ static int gpiochip_find_base(int ngpio)
+               /* found a free space? */
+               if (gdev->base + gdev->ngpio <= base)
+                       break;
+-              else
+-                      /* nope, check the space right before the chip */
+-                      base = gdev->base - ngpio;
++              /* nope, check the space right before the chip */
++              base = gdev->base - ngpio;
+       }
+       if (gpio_is_valid(base)) {
+@@ -2481,8 +2480,7 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
+                       ret = gpiod_direction_input(desc);
+                       goto set_output_flag;
+               }
+-      }
+-      else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {
++      } else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {
+               ret = gpio_set_config(desc, PIN_CONFIG_DRIVE_OPEN_SOURCE);
+               if (!ret)
+                       goto set_output_value;
+@@ -2656,9 +2654,9 @@ static int gpiod_get_raw_value_commit(const struct gpio_desc *desc)
+ static int gpio_chip_get_multiple(struct gpio_chip *gc,
+                                 unsigned long *mask, unsigned long *bits)
+ {
+-      if (gc->get_multiple) {
++      if (gc->get_multiple)
+               return gc->get_multiple(gc, mask, bits);
+-      } else if (gc->get) {
++      if (gc->get) {
+               int i, value;
+               for_each_set_bit(i, mask, gc->ngpio) {
+-- 
+2.35.1
+
diff --git a/queue-5.10/hamradio-baycom_epp-fix-return-type-of-baycom_send_p.patch b/queue-5.10/hamradio-baycom_epp-fix-return-type-of-baycom_send_p.patch
new file mode 100644 (file)
index 0000000..d21d3de
--- /dev/null
@@ -0,0 +1,52 @@
+From 3d622b0ac34d0ab30e104232b8fa65f4f421445b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 09:06:10 -0700
+Subject: hamradio: baycom_epp: Fix return type of baycom_send_packet()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit c5733e5b15d91ab679646ec3149e192996a27d5d ]
+
+With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
+indirect call targets are validated against the expected function
+pointer prototype to make sure the call target is valid to help mitigate
+ROP attacks. If they are not identical, there is a failure at run time,
+which manifests as either a kernel panic or thread getting killed. A
+proposed warning in clang aims to catch these at compile time, which
+reveals:
+
+  drivers/net/hamradio/baycom_epp.c:1119:25: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+          .ndo_start_xmit      = baycom_send_packet,
+                                ^~~~~~~~~~~~~~~~~~
+  1 error generated.
+
+->ndo_start_xmit() in 'struct net_device_ops' expects a return type of
+'netdev_tx_t', not 'int'. Adjust the return type of baycom_send_packet()
+to match the prototype's to resolve the warning and CFI failure.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1750
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20221102160610.1186145-1-nathan@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/hamradio/baycom_epp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
+index e4e4981ac1d2..eea9d47157cf 100644
+--- a/drivers/net/hamradio/baycom_epp.c
++++ b/drivers/net/hamradio/baycom_epp.c
+@@ -758,7 +758,7 @@ static void epp_bh(struct work_struct *work)
+  * ===================== network driver interface =========================
+  */
+-static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct baycom_state *bc = netdev_priv(dev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/hamradio-don-t-call-dev_kfree_skb-under-spin_lock_ir.patch b/queue-5.10/hamradio-don-t-call-dev_kfree_skb-under-spin_lock_ir.patch
new file mode 100644 (file)
index 0000000..6e46234
--- /dev/null
@@ -0,0 +1,62 @@
+From 555125a09c78c96259e0a07287bd4af289132b99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 22:21:46 +0800
+Subject: hamradio: don't call dev_kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 3727f742915f04f6fc550b80cf406999bd4e90d0 ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+It should use dev_kfree_skb_irq() or dev_consume_skb_irq() instead.
+The difference between them is free reason, dev_kfree_skb_irq() means
+the SKB is dropped in error and dev_consume_skb_irq() means the SKB
+is consumed in normal.
+
+In scc_discard_buffers(), dev_kfree_skb() is called to discard the SKBs,
+so replace it with dev_kfree_skb_irq().
+
+In scc_net_tx(), dev_kfree_skb() is called to drop the SKB that exceed
+queue length, so replace it with dev_kfree_skb_irq().
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/hamradio/scc.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
+index 36eeb80406f2..eeb6c47d8167 100644
+--- a/drivers/net/hamradio/scc.c
++++ b/drivers/net/hamradio/scc.c
+@@ -300,12 +300,12 @@ static inline void scc_discard_buffers(struct scc_channel *scc)
+       spin_lock_irqsave(&scc->lock, flags);   
+       if (scc->tx_buff != NULL)
+       {
+-              dev_kfree_skb(scc->tx_buff);
++              dev_kfree_skb_irq(scc->tx_buff);
+               scc->tx_buff = NULL;
+       }
+       
+       while (!skb_queue_empty(&scc->tx_queue))
+-              dev_kfree_skb(skb_dequeue(&scc->tx_queue));
++              dev_kfree_skb_irq(skb_dequeue(&scc->tx_queue));
+       spin_unlock_irqrestore(&scc->lock, flags);
+ }
+@@ -1667,7 +1667,7 @@ static netdev_tx_t scc_net_tx(struct sk_buff *skb, struct net_device *dev)
+       if (skb_queue_len(&scc->tx_queue) > scc->dev->tx_queue_len) {
+               struct sk_buff *skb_del;
+               skb_del = skb_dequeue(&scc->tx_queue);
+-              dev_kfree_skb(skb_del);
++              dev_kfree_skb_irq(skb_del);
+       }
+       skb_queue_tail(&scc->tx_queue, skb);
+       netif_trans_update(dev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/hfs-fix-oob-read-in-__hfs_brec_find.patch b/queue-5.10/hfs-fix-oob-read-in-__hfs_brec_find.patch
new file mode 100644 (file)
index 0000000..d4dbd9f
--- /dev/null
@@ -0,0 +1,81 @@
+From 47c150cc6fbeb265c261a0c605c62fc539f7f39e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Nov 2022 06:59:59 +0000
+Subject: hfs: fix OOB Read in __hfs_brec_find
+
+From: ZhangPeng <zhangpeng362@huawei.com>
+
+[ Upstream commit 8d824e69d9f3fa3121b2dda25053bae71e2460d2 ]
+
+Syzbot reported a OOB read bug:
+
+==================================================================
+BUG: KASAN: slab-out-of-bounds in hfs_strcmp+0x117/0x190
+fs/hfs/string.c:84
+Read of size 1 at addr ffff88807eb62c4e by task kworker/u4:1/11
+CPU: 1 PID: 11 Comm: kworker/u4:1 Not tainted
+6.1.0-rc6-syzkaller-00308-g644e9524388a #0
+Workqueue: writeback wb_workfn (flush-7:0)
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x1b1/0x28e lib/dump_stack.c:106
+ print_address_description+0x74/0x340 mm/kasan/report.c:284
+ print_report+0x107/0x1f0 mm/kasan/report.c:395
+ kasan_report+0xcd/0x100 mm/kasan/report.c:495
+ hfs_strcmp+0x117/0x190 fs/hfs/string.c:84
+ __hfs_brec_find+0x213/0x5c0 fs/hfs/bfind.c:75
+ hfs_brec_find+0x276/0x520 fs/hfs/bfind.c:138
+ hfs_write_inode+0x34c/0xb40 fs/hfs/inode.c:462
+ write_inode fs/fs-writeback.c:1440 [inline]
+
+If the input inode of hfs_write_inode() is incorrect:
+struct inode
+  struct hfs_inode_info
+    struct hfs_cat_key
+      struct hfs_name
+        u8 len # len is greater than HFS_NAMELEN(31) which is the
+maximum length of an HFS filename
+
+OOB read occurred:
+hfs_write_inode()
+  hfs_brec_find()
+    __hfs_brec_find()
+      hfs_cat_keycmp()
+        hfs_strcmp() # OOB read occurred due to len is too large
+
+Fix this by adding a Check on len in hfs_write_inode() before calling
+hfs_brec_find().
+
+Link: https://lkml.kernel.org/r/20221130065959.2168236-1-zhangpeng362@huawei.com
+Signed-off-by: ZhangPeng <zhangpeng362@huawei.com>
+Reported-by: <syzbot+e836ff7133ac02be825f@syzkaller.appspotmail.com>
+Cc: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Cc: Ira Weiny <ira.weiny@intel.com>
+Cc: Jeff Layton <jlayton@kernel.org>
+Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Nanyong Sun <sunnanyong@huawei.com>
+Cc: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/hfs/inode.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
+index f35a37c65e5f..e9b4249a4b01 100644
+--- a/fs/hfs/inode.c
++++ b/fs/hfs/inode.c
+@@ -454,6 +454,8 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+               /* panic? */
+               return -EIO;
++      if (HFS_I(main_inode)->cat_key.CName.len > HFS_NAMELEN)
++              return -EIO;
+       fd.search_key->cat = HFS_I(main_inode)->cat_key;
+       if (hfs_brec_find(&fd))
+               /* panic? */
+-- 
+2.35.1
+
diff --git a/queue-5.10/hfs-fix-oob-write-in-hfs_asc2mac.patch b/queue-5.10/hfs-fix-oob-write-in-hfs_asc2mac.patch
new file mode 100644 (file)
index 0000000..b96f8cf
--- /dev/null
@@ -0,0 +1,66 @@
+From 11a2b136cc91def3d790f510f910ad4467489d14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 03:00:38 +0000
+Subject: hfs: Fix OOB Write in hfs_asc2mac
+
+From: ZhangPeng <zhangpeng362@huawei.com>
+
+[ Upstream commit c53ed55cb275344086e32a7080a6b19cb183650b ]
+
+Syzbot reported a OOB Write bug:
+
+loop0: detected capacity change from 0 to 64
+==================================================================
+BUG: KASAN: slab-out-of-bounds in hfs_asc2mac+0x467/0x9a0
+fs/hfs/trans.c:133
+Write of size 1 at addr ffff88801848314e by task syz-executor391/3632
+
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x1b1/0x28e lib/dump_stack.c:106
+ print_address_description+0x74/0x340 mm/kasan/report.c:284
+ print_report+0x107/0x1f0 mm/kasan/report.c:395
+ kasan_report+0xcd/0x100 mm/kasan/report.c:495
+ hfs_asc2mac+0x467/0x9a0 fs/hfs/trans.c:133
+ hfs_cat_build_key+0x92/0x170 fs/hfs/catalog.c:28
+ hfs_lookup+0x1ab/0x2c0 fs/hfs/dir.c:31
+ lookup_open fs/namei.c:3391 [inline]
+ open_last_lookups fs/namei.c:3481 [inline]
+ path_openat+0x10e6/0x2df0 fs/namei.c:3710
+ do_filp_open+0x264/0x4f0 fs/namei.c:3740
+
+If in->len is much larger than HFS_NAMELEN(31) which is the maximum
+length of an HFS filename, a OOB write could occur in hfs_asc2mac(). In
+that case, when the dst reaches the boundary, the srclen is still
+greater than 0, which causes a OOB write.
+Fix this by adding a check on dstlen in while() before writing to dst
+address.
+
+Link: https://lkml.kernel.org/r/20221202030038.1391945-1-zhangpeng362@huawei.com
+Fixes: 328b92278650 ("[PATCH] hfs: NLS support")
+Signed-off-by: ZhangPeng <zhangpeng362@huawei.com>
+Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Reported-by: <syzbot+dc3b1cf9111ab5fe98e7@syzkaller.appspotmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/hfs/trans.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/hfs/trans.c b/fs/hfs/trans.c
+index 39f5e343bf4d..fdb0edb8a607 100644
+--- a/fs/hfs/trans.c
++++ b/fs/hfs/trans.c
+@@ -109,7 +109,7 @@ void hfs_asc2mac(struct super_block *sb, struct hfs_name *out, const struct qstr
+       if (nls_io) {
+               wchar_t ch;
+-              while (srclen > 0) {
++              while (srclen > 0 && dstlen > 0) {
+                       size = nls_io->char2uni(src, srclen, &ch);
+                       if (size < 0) {
+                               ch = '?';
+-- 
+2.35.1
+
diff --git a/queue-5.10/hid-hid-sensor-custom-set-fixed-size-for-custom-attr.patch b/queue-5.10/hid-hid-sensor-custom-set-fixed-size-for-custom-attr.patch
new file mode 100644 (file)
index 0000000..003199b
--- /dev/null
@@ -0,0 +1,48 @@
+From afe393125b30a5edb9690816114a895880d01db9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 13:13:26 +0100
+Subject: HID: hid-sensor-custom: set fixed size for custom attributes
+
+From: Marcus Folkesson <marcus.folkesson@gmail.com>
+
+[ Upstream commit 9d013910df22de91333a0acc81d1dbb115bd76f6 ]
+
+This is no bugfix (so no Fixes: tag is necessary) as it is
+taken care of in hid_sensor_custom_add_attributes().
+
+The motivation for this patch is that:
+hid_sensor_custom_field.attr_name and
+hid_sensor_custom_field.attrs
+has the size of HID_CUSTOM_TOTAL_ATTRS and used in same context.
+
+We compare against HID_CUSTOM_TOTAL_ATTRS when
+looping through hid_custom_attrs.
+
+We will silent the smatch error:
+hid_sensor_custom_add_attributes() error: buffer overflow
+'hid_custom_attrs' 8 <= 10
+
+Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
+Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-sensor-custom.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-sensor-custom.c b/drivers/hid/hid-sensor-custom.c
+index 4d25577a8573..971600a6397a 100644
+--- a/drivers/hid/hid-sensor-custom.c
++++ b/drivers/hid/hid-sensor-custom.c
+@@ -59,7 +59,7 @@ struct hid_sensor_sample {
+       u32 raw_len;
+ } __packed;
+-static struct attribute hid_custom_attrs[] = {
++static struct attribute hid_custom_attrs[HID_CUSTOM_TOTAL_ATTRS] = {
+       {.name = "name", .mode = S_IRUGO},
+       {.name = "units", .mode = S_IRUGO},
+       {.name = "unit-expo", .mode = S_IRUGO},
+-- 
+2.35.1
+
diff --git a/queue-5.10/hsi-omap_ssi_core-fix-error-handling-in-ssi_init.patch b/queue-5.10/hsi-omap_ssi_core-fix-error-handling-in-ssi_init.patch
new file mode 100644 (file)
index 0000000..026a6aa
--- /dev/null
@@ -0,0 +1,45 @@
+From 47b0bb7f968ea044ec146ec190f3e4da1d0e8a01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Nov 2022 11:33:32 +0000
+Subject: HSI: omap_ssi_core: Fix error handling in ssi_init()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 3ffa9f713c39a213a08d9ff13ab983a8aa5d8b5d ]
+
+The ssi_init() returns the platform_driver_register() directly without
+checking its return value, if platform_driver_register() failed, the
+ssi_pdriver is not unregistered.
+Fix by unregister ssi_pdriver when the last platform_driver_register()
+failed.
+
+Fixes: 0fae198988b8 ("HSI: omap_ssi: built omap_ssi and omap_ssi_port into one module")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hsi/controllers/omap_ssi_core.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hsi/controllers/omap_ssi_core.c b/drivers/hsi/controllers/omap_ssi_core.c
+index 052cf3e92dd6..26f2c3c01297 100644
+--- a/drivers/hsi/controllers/omap_ssi_core.c
++++ b/drivers/hsi/controllers/omap_ssi_core.c
+@@ -631,7 +631,13 @@ static int __init ssi_init(void) {
+       if (ret)
+               return ret;
+-      return platform_driver_register(&ssi_port_pdriver);
++      ret = platform_driver_register(&ssi_port_pdriver);
++      if (ret) {
++              platform_driver_unregister(&ssi_pdriver);
++              return ret;
++      }
++
++      return 0;
+ }
+ module_init(ssi_init);
+-- 
+2.35.1
+
diff --git a/queue-5.10/hsi-omap_ssi_core-fix-possible-memory-leak-in-ssi_pr.patch b/queue-5.10/hsi-omap_ssi_core-fix-possible-memory-leak-in-ssi_pr.patch
new file mode 100644 (file)
index 0000000..ebfbd32
--- /dev/null
@@ -0,0 +1,41 @@
+From ab74dea5d709ec51cee8eb3ae42adbf50503e9a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Oct 2022 15:43:37 +0800
+Subject: HSI: omap_ssi_core: fix possible memory leak in ssi_probe()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 1aff514e1d2bd47854dbbdf867970b9d463d4c57 ]
+
+If ssi_add_controller() returns error, it should call hsi_put_controller()
+to give up the reference that was set in hsi_alloc_controller(), so that
+it can call hsi_controller_release() to free controller and ports that
+allocated in hsi_alloc_controller().
+
+Fixes: b209e047bc74 ("HSI: Introduce OMAP SSI driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hsi/controllers/omap_ssi_core.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hsi/controllers/omap_ssi_core.c b/drivers/hsi/controllers/omap_ssi_core.c
+index b23a576ed88a..052cf3e92dd6 100644
+--- a/drivers/hsi/controllers/omap_ssi_core.c
++++ b/drivers/hsi/controllers/omap_ssi_core.c
+@@ -502,8 +502,10 @@ static int ssi_probe(struct platform_device *pd)
+       platform_set_drvdata(pd, ssi);
+       err = ssi_add_controller(ssi, pd);
+-      if (err < 0)
++      if (err < 0) {
++              hsi_put_controller(ssi);
+               goto out1;
++      }
+       pm_runtime_enable(&pd->dev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/hsi-omap_ssi_core-fix-unbalanced-pm_runtime_disable.patch b/queue-5.10/hsi-omap_ssi_core-fix-unbalanced-pm_runtime_disable.patch
new file mode 100644 (file)
index 0000000..30aacb4
--- /dev/null
@@ -0,0 +1,38 @@
+From a6d980858a4b98012aa36f25baa72be48ee7d9b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 11:41:18 +0800
+Subject: HSI: omap_ssi_core: fix unbalanced pm_runtime_disable()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit f5181c35ed7ba0ceb6e42872aad1334d994b0175 ]
+
+In error label 'out1' path in ssi_probe(), the pm_runtime_enable()
+has not been called yet, so pm_runtime_disable() is not needed.
+
+Fixes: b209e047bc74 ("HSI: Introduce OMAP SSI driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hsi/controllers/omap_ssi_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hsi/controllers/omap_ssi_core.c b/drivers/hsi/controllers/omap_ssi_core.c
+index eb9820158318..b23a576ed88a 100644
+--- a/drivers/hsi/controllers/omap_ssi_core.c
++++ b/drivers/hsi/controllers/omap_ssi_core.c
+@@ -536,9 +536,9 @@ static int ssi_probe(struct platform_device *pd)
+       device_for_each_child(&pd->dev, NULL, ssi_remove_ports);
+ out2:
+       ssi_remove_controller(ssi);
++      pm_runtime_disable(&pd->dev);
+ out1:
+       platform_set_drvdata(pd, NULL);
+-      pm_runtime_disable(&pd->dev);
+       return err;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/hsr-add-a-rcu-read-lock-to-hsr_forward_skb.patch b/queue-5.10/hsr-add-a-rcu-read-lock-to-hsr_forward_skb.patch
new file mode 100644 (file)
index 0000000..d6b01ef
--- /dev/null
@@ -0,0 +1,55 @@
+From f672b7166495f9596cff7473f0152a6dcdec5379 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 17:48:09 +0100
+Subject: hsr: Add a rcu-read lock to hsr_forward_skb().
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 5aa2820177af650293b2f9f1873c1f6f8e4ad7a4 ]
+
+hsr_forward_skb() a skb and keeps information in an on-stack
+hsr_frame_info. hsr_get_node() assigns hsr_frame_info::node_src which is
+from a RCU list. This pointer is used later in hsr_forward_do().
+I don't see a reason why this pointer can't vanish midway since there is
+no guarantee that hsr_forward_skb() is invoked from an RCU read section.
+
+Use rcu_read_lock() to protect hsr_frame_info::node_src from its
+assignment until it is no longer used.
+
+Fixes: f266a683a4804 ("net/hsr: Better frame dispatch")
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_forward.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index cb9b54a7abd2..90b0ed16552b 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -545,11 +545,13 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
+ {
+       struct hsr_frame_info frame;
++      rcu_read_lock();
+       if (fill_frame_info(&frame, skb, port) < 0)
+               goto out_drop;
+       hsr_register_frame_in(frame.node_src, port, frame.sequence_nr);
+       hsr_forward_do(&frame);
++      rcu_read_unlock();
+       /* Gets called for ingress frames as well as egress from master port.
+        * So check and increment stats for master port only here.
+        */
+@@ -564,6 +566,7 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
+       return;
+ out_drop:
++      rcu_read_unlock();
+       port->dev->stats.tx_dropped++;
+       kfree_skb(skb);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/hsr-disable-netpoll.patch b/queue-5.10/hsr-disable-netpoll.patch
new file mode 100644 (file)
index 0000000..9d401bd
--- /dev/null
@@ -0,0 +1,133 @@
+From fdbf0507144cca123dd6a3b63717e427e89d52d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 17:48:11 +0100
+Subject: hsr: Disable netpoll.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit d5c7652eb16fa203d82546e0285136d7b321ffa9 ]
+
+The hsr device is a software device. Its
+net_device_ops::ndo_start_xmit() routine will process the packet and
+then pass the resulting skb to dev_queue_xmit().
+During processing, hsr acquires a lock with spin_lock_bh()
+(hsr_add_node()) which needs to be promoted to the _irq() suffix in
+order to avoid a potential deadlock.
+Then there are the warnings in dev_queue_xmit() (due to
+local_bh_disable() with disabled interrupts) left.
+
+Instead trying to address those (there is qdisc and…) for netpoll sake,
+just disable netpoll on hsr.
+
+Disable netpoll on hsr and replace the _irqsave() locking with _bh().
+
+Fixes: f421436a591d3 ("net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)")
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_device.c  | 14 ++++++--------
+ net/hsr/hsr_forward.c |  5 ++---
+ 2 files changed, 8 insertions(+), 11 deletions(-)
+
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index 7449c3c95317..037ad39564a4 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -278,7 +278,6 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+       __u8 type = HSR_TLV_LIFE_CHECK;
+       struct hsr_sup_payload *hsr_sp;
+       struct hsr_sup_tag *hsr_stag;
+-      unsigned long irqflags;
+       struct sk_buff *skb;
+       *interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL);
+@@ -299,7 +298,7 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+       set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version);
+       /* From HSRv1 on we have separate supervision sequence numbers. */
+-      spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags);
++      spin_lock_bh(&hsr->seqnr_lock);
+       if (hsr->prot_version > 0) {
+               hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr);
+               hsr->sup_sequence_nr++;
+@@ -307,7 +306,7 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+               hsr_stag->sequence_nr = htons(hsr->sequence_nr);
+               hsr->sequence_nr++;
+       }
+-      spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
++      spin_unlock_bh(&hsr->seqnr_lock);
+       hsr_stag->HSR_TLV_type = type;
+       /* TODO: Why 12 in HSRv0? */
+@@ -332,7 +331,6 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+       struct hsr_priv *hsr = master->hsr;
+       struct hsr_sup_payload *hsr_sp;
+       struct hsr_sup_tag *hsr_stag;
+-      unsigned long irqflags;
+       struct sk_buff *skb;
+       skb = hsr_init_skb(master);
+@@ -347,7 +345,7 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+       set_hsr_stag_HSR_ver(hsr_stag, (hsr->prot_version ? 1 : 0));
+       /* From HSRv1 on we have separate supervision sequence numbers. */
+-      spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags);
++      spin_lock_bh(&hsr->seqnr_lock);
+       hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr);
+       hsr->sup_sequence_nr++;
+       hsr_stag->HSR_TLV_type = PRP_TLV_LIFE_CHECK_DD;
+@@ -358,11 +356,11 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+       ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
+       if (skb_put_padto(skb, ETH_ZLEN)) {
+-              spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
++              spin_unlock_bh(&hsr->seqnr_lock);
+               return;
+       }
+-      spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
++      spin_unlock_bh(&hsr->seqnr_lock);
+       hsr_forward_skb(skb, master);
+ }
+@@ -443,7 +441,7 @@ void hsr_dev_setup(struct net_device *dev)
+       dev->header_ops = &hsr_header_ops;
+       dev->netdev_ops = &hsr_device_ops;
+       SET_NETDEV_DEVTYPE(dev, &hsr_type);
+-      dev->priv_flags |= IFF_NO_QUEUE;
++      dev->priv_flags |= IFF_NO_QUEUE | IFF_DISABLE_NETPOLL;
+       dev->needs_free_netdev = true;
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index 15653d3bb6ac..142bed7f1fea 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -437,7 +437,6 @@ static void handle_std_frame(struct sk_buff *skb,
+ {
+       struct hsr_port *port = frame->port_rcv;
+       struct hsr_priv *hsr = port->hsr;
+-      unsigned long irqflags;
+       frame->skb_hsr = NULL;
+       frame->skb_prp = NULL;
+@@ -447,10 +446,10 @@ static void handle_std_frame(struct sk_buff *skb,
+               frame->is_from_san = true;
+       } else {
+               /* Sequence nr for the master node */
+-              spin_lock_irqsave(&hsr->seqnr_lock, irqflags);
++              spin_lock_bh(&hsr->seqnr_lock);
+               frame->sequence_nr = hsr->sequence_nr;
+               hsr->sequence_nr++;
+-              spin_unlock_irqrestore(&hsr->seqnr_lock, irqflags);
++              spin_unlock_bh(&hsr->seqnr_lock);
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/hsr-synchronize-sending-frames-to-have-always-increm.patch b/queue-5.10/hsr-synchronize-sending-frames-to-have-always-increm.patch
new file mode 100644 (file)
index 0000000..209f2ea
--- /dev/null
@@ -0,0 +1,137 @@
+From 7f78b376ce3c2fcc196ac6ac33e782a32a6e6502 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 17:48:12 +0100
+Subject: hsr: Synchronize sending frames to have always incremented outgoing
+ seq nr.
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 06afd2c31d338fa762548580c1bf088703dd1e03 ]
+
+Sending frames via the hsr (master) device requires a sequence number
+which is tracked in hsr_priv::sequence_nr and protected by
+hsr_priv::seqnr_lock. Each time a new frame is sent, it will obtain a
+new id and then send it via the slave devices.
+Each time a packet is sent (via hsr_forward_do()) the sequence number is
+checked via hsr_register_frame_out() to ensure that a frame is not
+handled twice. This make sense for the receiving side to ensure that the
+frame is not injected into the stack twice after it has been received
+from both slave ports.
+
+There is no locking to cover the sending path which means the following
+scenario is possible:
+
+  CPU0                         CPU1
+  hsr_dev_xmit(skb1)           hsr_dev_xmit(skb2)
+   fill_frame_info()             fill_frame_info()
+    hsr_fill_frame_info()         hsr_fill_frame_info()
+     handle_std_frame()            handle_std_frame()
+      skb1's sequence_nr = 1
+                                    skb2's sequence_nr = 2
+   hsr_forward_do()              hsr_forward_do()
+
+                                   hsr_register_frame_out(, 2)  // okay, send)
+
+    hsr_register_frame_out(, 1) // stop, lower seq duplicate
+
+Both skbs (or their struct hsr_frame_info) received an unique id.
+However since skb2 was sent before skb1, the higher sequence number was
+recorded in hsr_register_frame_out() and the late arriving skb1 was
+dropped and never sent.
+
+This scenario has been observed in a three node HSR setup, with node1 +
+node2 having ping and iperf running in parallel. From time to time ping
+reported a missing packet. Based on tracing that missing ping packet did
+not leave the system.
+
+It might be possible (didn't check) to drop the sequence number check on
+the sending side. But if the higher sequence number leaves on wire
+before the lower does and the destination receives them in that order
+and it will drop the packet with the lower sequence number and never
+inject into the stack.
+Therefore it seems the only way is to lock the whole path from obtaining
+the sequence number and sending via dev_queue_xmit() and assuming the
+packets leave on wire in the same order (and don't get reordered by the
+NIC).
+
+Cover the whole path for the master interface from obtaining the ID
+until after it has been forwarded via hsr_forward_skb() to ensure the
+skbs are sent to the NIC in the order of the assigned sequence numbers.
+
+Fixes: f421436a591d3 ("net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)")
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_device.c  | 12 +++++++-----
+ net/hsr/hsr_forward.c |  3 +--
+ 2 files changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index 037ad39564a4..84e6ef4f3525 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -219,7 +219,9 @@ static netdev_tx_t hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev)
+               skb->dev = master->dev;
+               skb_reset_mac_header(skb);
+               skb_reset_mac_len(skb);
++              spin_lock_bh(&hsr->seqnr_lock);
+               hsr_forward_skb(skb, master);
++              spin_unlock_bh(&hsr->seqnr_lock);
+       } else {
+               atomic_long_inc(&dev->tx_dropped);
+               dev_kfree_skb_any(skb);
+@@ -306,7 +308,6 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+               hsr_stag->sequence_nr = htons(hsr->sequence_nr);
+               hsr->sequence_nr++;
+       }
+-      spin_unlock_bh(&hsr->seqnr_lock);
+       hsr_stag->HSR_TLV_type = type;
+       /* TODO: Why 12 in HSRv0? */
+@@ -317,11 +318,13 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+       hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
+       ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
+-      if (skb_put_padto(skb, ETH_ZLEN))
++      if (skb_put_padto(skb, ETH_ZLEN)) {
++              spin_unlock_bh(&hsr->seqnr_lock);
+               return;
++      }
+       hsr_forward_skb(skb, master);
+-
++      spin_unlock_bh(&hsr->seqnr_lock);
+       return;
+ }
+@@ -360,9 +363,8 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+               return;
+       }
+-      spin_unlock_bh(&hsr->seqnr_lock);
+-
+       hsr_forward_skb(skb, master);
++      spin_unlock_bh(&hsr->seqnr_lock);
+ }
+ /* Announce (supervision frame) timer function
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index 142bed7f1fea..aec48e670fb6 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -446,10 +446,9 @@ static void handle_std_frame(struct sk_buff *skb,
+               frame->is_from_san = true;
+       } else {
+               /* Sequence nr for the master node */
+-              spin_lock_bh(&hsr->seqnr_lock);
++              lockdep_assert_held(&hsr->seqnr_lock);
+               frame->sequence_nr = hsr->sequence_nr;
+               hsr->sequence_nr++;
+-              spin_unlock_bh(&hsr->seqnr_lock);
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/hsr-synchronize-sequence-number-updates.patch b/queue-5.10/hsr-synchronize-sequence-number-updates.patch
new file mode 100644 (file)
index 0000000..d71c6f9
--- /dev/null
@@ -0,0 +1,101 @@
+From 8964182a58ba96444d562a4f3027539b1211b2a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 17:48:13 +0100
+Subject: hsr: Synchronize sequence number updates.
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 5c7aa13210c3abdd34fd421f62347665ec6eb551 ]
+
+hsr_register_frame_out() compares new sequence_nr vs the old one
+recorded in hsr_node::seq_out and if the new sequence_nr is higher then
+it will be written to hsr_node::seq_out as the new value.
+
+This operation isn't locked so it is possible that two frames with the
+same sequence number arrive (via the two slave devices) and are fed to
+hsr_register_frame_out() at the same time. Both will pass the check and
+update the sequence counter later to the same value. As a result the
+content of the same packet is fed into the stack twice.
+
+This was noticed by running ping and observing DUP being reported from
+time to time.
+
+Instead of using the hsr_priv::seqnr_lock for the whole receive path (as
+it is for sending in the master node) add an additional lock that is only
+used for sequence number checks and updates.
+
+Add a per-node lock that is used during sequence number reads and
+updates.
+
+Fixes: f421436a591d3 ("net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)")
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_framereg.c | 9 ++++++++-
+ net/hsr/hsr_framereg.h | 2 ++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
+index 805f974923b9..20cb6b7dbc69 100644
+--- a/net/hsr/hsr_framereg.c
++++ b/net/hsr/hsr_framereg.c
+@@ -159,6 +159,7 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,
+               return NULL;
+       ether_addr_copy(new_node->macaddress_A, addr);
++      spin_lock_init(&new_node->seq_out_lock);
+       /* We are only interested in time diffs here, so use current jiffies
+        * as initialization. (0 could trigger an spurious ring error warning).
+@@ -311,6 +312,7 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
+               goto done;
+       ether_addr_copy(node_real->macaddress_B, ethhdr->h_source);
++      spin_lock_bh(&node_real->seq_out_lock);
+       for (i = 0; i < HSR_PT_PORTS; i++) {
+               if (!node_curr->time_in_stale[i] &&
+                   time_after(node_curr->time_in[i], node_real->time_in[i])) {
+@@ -321,6 +323,7 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
+               if (seq_nr_after(node_curr->seq_out[i], node_real->seq_out[i]))
+                       node_real->seq_out[i] = node_curr->seq_out[i];
+       }
++      spin_unlock_bh(&node_real->seq_out_lock);
+       node_real->addr_B_port = port_rcv->type;
+       spin_lock_bh(&hsr->list_lock);
+@@ -413,13 +416,17 @@ void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port,
+ int hsr_register_frame_out(struct hsr_port *port, struct hsr_node *node,
+                          u16 sequence_nr)
+ {
++      spin_lock_bh(&node->seq_out_lock);
+       if (seq_nr_before_or_eq(sequence_nr, node->seq_out[port->type]) &&
+           time_is_after_jiffies(node->time_out[port->type] +
+-          msecs_to_jiffies(HSR_ENTRY_FORGET_TIME)))
++          msecs_to_jiffies(HSR_ENTRY_FORGET_TIME))) {
++              spin_unlock_bh(&node->seq_out_lock);
+               return 1;
++      }
+       node->time_out[port->type] = jiffies;
+       node->seq_out[port->type] = sequence_nr;
++      spin_unlock_bh(&node->seq_out_lock);
+       return 0;
+ }
+diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h
+index d9628e7a5f05..5a771cb3f032 100644
+--- a/net/hsr/hsr_framereg.h
++++ b/net/hsr/hsr_framereg.h
+@@ -69,6 +69,8 @@ void prp_update_san_info(struct hsr_node *node, bool is_sup);
+ struct hsr_node {
+       struct list_head        mac_list;
++      /* Protect R/W access to seq_out */
++      spinlock_t              seq_out_lock;
+       unsigned char           macaddress_A[ETH_ALEN];
+       unsigned char           macaddress_B[ETH_ALEN];
+       /* Local slave through which AddrB frames are received from this node */
+-- 
+2.35.1
+
diff --git a/queue-5.10/hugetlbfs-fix-null-ptr-deref-in-hugetlbfs_parse_para.patch b/queue-5.10/hugetlbfs-fix-null-ptr-deref-in-hugetlbfs_parse_para.patch
new file mode 100644 (file)
index 0000000..8e40fff
--- /dev/null
@@ -0,0 +1,96 @@
+From 1b3c89ffcdac050e2503393fedb8197e9f2a33cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Oct 2022 07:16:08 +0800
+Subject: hugetlbfs: fix null-ptr-deref in hugetlbfs_parse_param()
+
+From: Hawkins Jiawei <yin31149@gmail.com>
+
+[ Upstream commit 26215b7ee923b9251f7bb12c4e5f09dc465d35f2 ]
+
+Syzkaller reports a null-ptr-deref bug as follows:
+======================================================
+KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+RIP: 0010:hugetlbfs_parse_param+0x1dd/0x8e0 fs/hugetlbfs/inode.c:1380
+[...]
+Call Trace:
+ <TASK>
+ vfs_parse_fs_param fs/fs_context.c:148 [inline]
+ vfs_parse_fs_param+0x1f9/0x3c0 fs/fs_context.c:129
+ vfs_parse_fs_string+0xdb/0x170 fs/fs_context.c:191
+ generic_parse_monolithic+0x16f/0x1f0 fs/fs_context.c:231
+ do_new_mount fs/namespace.c:3036 [inline]
+ path_mount+0x12de/0x1e20 fs/namespace.c:3370
+ do_mount fs/namespace.c:3383 [inline]
+ __do_sys_mount fs/namespace.c:3591 [inline]
+ __se_sys_mount fs/namespace.c:3568 [inline]
+ __x64_sys_mount+0x27f/0x300 fs/namespace.c:3568
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+ [...]
+ </TASK>
+======================================================
+
+According to commit "vfs: parse: deal with zero length string value",
+kernel will set the param->string to null pointer in vfs_parse_fs_string()
+if fs string has zero length.
+
+Yet the problem is that, hugetlbfs_parse_param() will dereference the
+param->string, without checking whether it is a null pointer.  To be more
+specific, if hugetlbfs_parse_param() parses an illegal mount parameter,
+such as "size=,", kernel will constructs struct fs_parameter with null
+pointer in vfs_parse_fs_string(), then passes this struct fs_parameter to
+hugetlbfs_parse_param(), which triggers the above null-ptr-deref bug.
+
+This patch solves it by adding sanity check on param->string
+in hugetlbfs_parse_param().
+
+Link: https://lkml.kernel.org/r/20221020231609.4810-1-yin31149@gmail.com
+Reported-by: syzbot+a3e6acd85ded5c16a709@syzkaller.appspotmail.com
+Tested-by: syzbot+a3e6acd85ded5c16a709@syzkaller.appspotmail.com
+  Link: https://lore.kernel.org/all/0000000000005ad00405eb7148c6@google.com/
+Signed-off-by: Hawkins Jiawei <yin31149@gmail.com>
+Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Hawkins Jiawei <yin31149@gmail.com>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Cc: Ian Kent <raven@themaw.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/hugetlbfs/inode.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+index a2f43f1a85f8..5181e6d4e18c 100644
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -1261,7 +1261,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
+       case Opt_size:
+               /* memparse() will accept a K/M/G without a digit */
+-              if (!isdigit(param->string[0]))
++              if (!param->string || !isdigit(param->string[0]))
+                       goto bad_val;
+               ctx->max_size_opt = memparse(param->string, &rest);
+               ctx->max_val_type = SIZE_STD;
+@@ -1271,7 +1271,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
+       case Opt_nr_inodes:
+               /* memparse() will accept a K/M/G without a digit */
+-              if (!isdigit(param->string[0]))
++              if (!param->string || !isdigit(param->string[0]))
+                       goto bad_val;
+               ctx->nr_inodes = memparse(param->string, &rest);
+               return 0;
+@@ -1287,7 +1287,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
+       case Opt_min_size:
+               /* memparse() will accept a K/M/G without a digit */
+-              if (!isdigit(param->string[0]))
++              if (!param->string || !isdigit(param->string[0]))
+                       goto bad_val;
+               ctx->min_size_opt = memparse(param->string, &rest);
+               ctx->min_val_type = SIZE_STD;
+-- 
+2.35.1
+
diff --git a/queue-5.10/hwmon-jc42-convert-register-access-and-caching-to-re.patch b/queue-5.10/hwmon-jc42-convert-register-access-and-caching-to-re.patch
new file mode 100644 (file)
index 0000000..7be5ef9
--- /dev/null
@@ -0,0 +1,421 @@
+From 06ca2e42a65c2a9e97e39e027e4d1cb8f8773479 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Oct 2022 23:31:56 +0200
+Subject: hwmon: (jc42) Convert register access and caching to regmap/regcache
+
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+
+[ Upstream commit 8f2fa4726faf01094d7a5be7bd0c120c565f54d9 ]
+
+Switch the jc42 driver to use an I2C regmap to access the registers.
+Also move over to regmap's built-in caching instead of adding a
+custom caching implementation. This works for JC42_REG_TEMP_UPPER,
+JC42_REG_TEMP_LOWER and JC42_REG_TEMP_CRITICAL as these values never
+change except when explicitly written. The cache For JC42_REG_TEMP is
+dropped (regmap can't cache it because it's volatile, meaning it can
+change at any time) as well for simplicity and consistency with other
+drivers.
+
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://lore.kernel.org/r/20221023213157.11078-2-martin.blumenstingl@googlemail.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Stable-dep-of: 084ed144c448 ("hwmon: (jc42) Restore the min/max/critical temperatures on resume")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/Kconfig |   1 +
+ drivers/hwmon/jc42.c  | 233 ++++++++++++++++++++++++------------------
+ 2 files changed, 132 insertions(+), 102 deletions(-)
+
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index f741c7492ee4..8a427467a842 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -766,6 +766,7 @@ config SENSORS_IT87
+ config SENSORS_JC42
+       tristate "JEDEC JC42.4 compliant memory module temperature sensors"
+       depends on I2C
++      select REGMAP_I2C
+       help
+         If you say yes here, you get support for JEDEC JC42.4 compliant
+         temperature sensors, which are used on many DDR3 memory modules for
+diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c
+index 4a03d010ec5a..9a2a062eb7b8 100644
+--- a/drivers/hwmon/jc42.c
++++ b/drivers/hwmon/jc42.c
+@@ -19,6 +19,7 @@
+ #include <linux/err.h>
+ #include <linux/mutex.h>
+ #include <linux/of.h>
++#include <linux/regmap.h>
+ /* Addresses to scan */
+ static const unsigned short normal_i2c[] = {
+@@ -189,31 +190,14 @@ static struct jc42_chips jc42_chips[] = {
+       { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK },
+ };
+-enum temp_index {
+-      t_input = 0,
+-      t_crit,
+-      t_min,
+-      t_max,
+-      t_num_temp
+-};
+-
+-static const u8 temp_regs[t_num_temp] = {
+-      [t_input] = JC42_REG_TEMP,
+-      [t_crit] = JC42_REG_TEMP_CRITICAL,
+-      [t_min] = JC42_REG_TEMP_LOWER,
+-      [t_max] = JC42_REG_TEMP_UPPER,
+-};
+-
+ /* Each client has this additional data */
+ struct jc42_data {
+-      struct i2c_client *client;
+       struct mutex    update_lock;    /* protect register access */
++      struct regmap   *regmap;
+       bool            extended;       /* true if extended range supported */
+       bool            valid;
+-      unsigned long   last_updated;   /* In jiffies */
+       u16             orig_config;    /* original configuration */
+       u16             config;         /* current configuration */
+-      u16             temp[t_num_temp];/* Temperatures */
+ };
+ #define JC42_TEMP_MIN_EXTENDED        (-40000)
+@@ -238,85 +222,102 @@ static int jc42_temp_from_reg(s16 reg)
+       return reg * 125 / 2;
+ }
+-static struct jc42_data *jc42_update_device(struct device *dev)
+-{
+-      struct jc42_data *data = dev_get_drvdata(dev);
+-      struct i2c_client *client = data->client;
+-      struct jc42_data *ret = data;
+-      int i, val;
+-
+-      mutex_lock(&data->update_lock);
+-
+-      if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+-              for (i = 0; i < t_num_temp; i++) {
+-                      val = i2c_smbus_read_word_swapped(client, temp_regs[i]);
+-                      if (val < 0) {
+-                              ret = ERR_PTR(val);
+-                              goto abort;
+-                      }
+-                      data->temp[i] = val;
+-              }
+-              data->last_updated = jiffies;
+-              data->valid = true;
+-      }
+-abort:
+-      mutex_unlock(&data->update_lock);
+-      return ret;
+-}
+-
+ static int jc42_read(struct device *dev, enum hwmon_sensor_types type,
+                    u32 attr, int channel, long *val)
+ {
+-      struct jc42_data *data = jc42_update_device(dev);
+-      int temp, hyst;
++      struct jc42_data *data = dev_get_drvdata(dev);
++      unsigned int regval;
++      int ret, temp, hyst;
+-      if (IS_ERR(data))
+-              return PTR_ERR(data);
++      mutex_lock(&data->update_lock);
+       switch (attr) {
+       case hwmon_temp_input:
+-              *val = jc42_temp_from_reg(data->temp[t_input]);
+-              return 0;
++              ret = regmap_read(data->regmap, JC42_REG_TEMP, &regval);
++              if (ret)
++                      break;
++
++              *val = jc42_temp_from_reg(regval);
++              break;
+       case hwmon_temp_min:
+-              *val = jc42_temp_from_reg(data->temp[t_min]);
+-              return 0;
++              ret = regmap_read(data->regmap, JC42_REG_TEMP_LOWER, &regval);
++              if (ret)
++                      break;
++
++              *val = jc42_temp_from_reg(regval);
++              break;
+       case hwmon_temp_max:
+-              *val = jc42_temp_from_reg(data->temp[t_max]);
+-              return 0;
++              ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, &regval);
++              if (ret)
++                      break;
++
++              *val = jc42_temp_from_reg(regval);
++              break;
+       case hwmon_temp_crit:
+-              *val = jc42_temp_from_reg(data->temp[t_crit]);
+-              return 0;
++              ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,
++                                &regval);
++              if (ret)
++                      break;
++
++              *val = jc42_temp_from_reg(regval);
++              break;
+       case hwmon_temp_max_hyst:
+-              temp = jc42_temp_from_reg(data->temp[t_max]);
++              ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, &regval);
++              if (ret)
++                      break;
++
++              temp = jc42_temp_from_reg(regval);
+               hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK)
+                                               >> JC42_CFG_HYST_SHIFT];
+               *val = temp - hyst;
+-              return 0;
++              break;
+       case hwmon_temp_crit_hyst:
+-              temp = jc42_temp_from_reg(data->temp[t_crit]);
++              ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,
++                                &regval);
++              if (ret)
++                      break;
++
++              temp = jc42_temp_from_reg(regval);
+               hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK)
+                                               >> JC42_CFG_HYST_SHIFT];
+               *val = temp - hyst;
+-              return 0;
++              break;
+       case hwmon_temp_min_alarm:
+-              *val = (data->temp[t_input] >> JC42_ALARM_MIN_BIT) & 1;
+-              return 0;
++              ret = regmap_read(data->regmap, JC42_REG_TEMP, &regval);
++              if (ret)
++                      break;
++
++              *val = (regval >> JC42_ALARM_MIN_BIT) & 1;
++              break;
+       case hwmon_temp_max_alarm:
+-              *val = (data->temp[t_input] >> JC42_ALARM_MAX_BIT) & 1;
+-              return 0;
++              ret = regmap_read(data->regmap, JC42_REG_TEMP, &regval);
++              if (ret)
++                      break;
++
++              *val = (regval >> JC42_ALARM_MAX_BIT) & 1;
++              break;
+       case hwmon_temp_crit_alarm:
+-              *val = (data->temp[t_input] >> JC42_ALARM_CRIT_BIT) & 1;
+-              return 0;
++              ret = regmap_read(data->regmap, JC42_REG_TEMP, &regval);
++              if (ret)
++                      break;
++
++              *val = (regval >> JC42_ALARM_CRIT_BIT) & 1;
++              break;
+       default:
+-              return -EOPNOTSUPP;
++              ret = -EOPNOTSUPP;
++              break;
+       }
++
++      mutex_unlock(&data->update_lock);
++
++      return ret;
+ }
+ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+                     u32 attr, int channel, long val)
+ {
+       struct jc42_data *data = dev_get_drvdata(dev);
+-      struct i2c_client *client = data->client;
++      unsigned int regval;
+       int diff, hyst;
+       int ret;
+@@ -324,21 +325,23 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+       switch (attr) {
+       case hwmon_temp_min:
+-              data->temp[t_min] = jc42_temp_to_reg(val, data->extended);
+-              ret = i2c_smbus_write_word_swapped(client, temp_regs[t_min],
+-                                                 data->temp[t_min]);
++              ret = regmap_write(data->regmap, JC42_REG_TEMP_LOWER,
++                                 jc42_temp_to_reg(val, data->extended));
+               break;
+       case hwmon_temp_max:
+-              data->temp[t_max] = jc42_temp_to_reg(val, data->extended);
+-              ret = i2c_smbus_write_word_swapped(client, temp_regs[t_max],
+-                                                 data->temp[t_max]);
++              ret = regmap_write(data->regmap, JC42_REG_TEMP_UPPER,
++                                 jc42_temp_to_reg(val, data->extended));
+               break;
+       case hwmon_temp_crit:
+-              data->temp[t_crit] = jc42_temp_to_reg(val, data->extended);
+-              ret = i2c_smbus_write_word_swapped(client, temp_regs[t_crit],
+-                                                 data->temp[t_crit]);
++              ret = regmap_write(data->regmap, JC42_REG_TEMP_CRITICAL,
++                                 jc42_temp_to_reg(val, data->extended));
+               break;
+       case hwmon_temp_crit_hyst:
++              ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,
++                                &regval);
++              if (ret)
++                      return ret;
++
+               /*
+                * JC42.4 compliant chips only support four hysteresis values.
+                * Pick best choice and go from there.
+@@ -346,7 +349,7 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+               val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED
+                                                    : JC42_TEMP_MIN) - 6000,
+                               JC42_TEMP_MAX);
+-              diff = jc42_temp_from_reg(data->temp[t_crit]) - val;
++              diff = jc42_temp_from_reg(regval) - val;
+               hyst = 0;
+               if (diff > 0) {
+                       if (diff < 2250)
+@@ -358,9 +361,8 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+               }
+               data->config = (data->config & ~JC42_CFG_HYST_MASK) |
+                               (hyst << JC42_CFG_HYST_SHIFT);
+-              ret = i2c_smbus_write_word_swapped(data->client,
+-                                                 JC42_REG_CONFIG,
+-                                                 data->config);
++              ret = regmap_write(data->regmap, JC42_REG_CONFIG,
++                                 data->config);
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+@@ -458,51 +460,80 @@ static const struct hwmon_chip_info jc42_chip_info = {
+       .info = jc42_info,
+ };
++static bool jc42_readable_reg(struct device *dev, unsigned int reg)
++{
++      return (reg >= JC42_REG_CAP && reg <= JC42_REG_DEVICEID) ||
++              reg == JC42_REG_SMBUS;
++}
++
++static bool jc42_writable_reg(struct device *dev, unsigned int reg)
++{
++      return (reg >= JC42_REG_CONFIG && reg <= JC42_REG_TEMP_CRITICAL) ||
++              reg == JC42_REG_SMBUS;
++}
++
++static bool jc42_volatile_reg(struct device *dev, unsigned int reg)
++{
++      return reg == JC42_REG_CONFIG || reg == JC42_REG_TEMP;
++}
++
++static const struct regmap_config jc42_regmap_config = {
++      .reg_bits = 8,
++      .val_bits = 16,
++      .val_format_endian = REGMAP_ENDIAN_BIG,
++      .max_register = JC42_REG_SMBUS,
++      .writeable_reg = jc42_writable_reg,
++      .readable_reg = jc42_readable_reg,
++      .volatile_reg = jc42_volatile_reg,
++      .cache_type = REGCACHE_RBTREE,
++};
++
+ static int jc42_probe(struct i2c_client *client)
+ {
+       struct device *dev = &client->dev;
+       struct device *hwmon_dev;
++      unsigned int config, cap;
+       struct jc42_data *data;
+-      int config, cap;
++      int ret;
+       data = devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+-      data->client = client;
++      data->regmap = devm_regmap_init_i2c(client, &jc42_regmap_config);
++      if (IS_ERR(data->regmap))
++              return PTR_ERR(data->regmap);
++
+       i2c_set_clientdata(client, data);
+       mutex_init(&data->update_lock);
+-      cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP);
+-      if (cap < 0)
+-              return cap;
++      ret = regmap_read(data->regmap, JC42_REG_CAP, &cap);
++      if (ret)
++              return ret;
+       data->extended = !!(cap & JC42_CAP_RANGE);
+       if (device_property_read_bool(dev, "smbus-timeout-disable")) {
+-              int smbus;
+-
+               /*
+                * Not all chips support this register, but from a
+                * quick read of various datasheets no chip appears
+                * incompatible with the below attempt to disable
+                * the timeout. And the whole thing is opt-in...
+                */
+-              smbus = i2c_smbus_read_word_swapped(client, JC42_REG_SMBUS);
+-              if (smbus < 0)
+-                      return smbus;
+-              i2c_smbus_write_word_swapped(client, JC42_REG_SMBUS,
+-                                           smbus | SMBUS_STMOUT);
++              ret = regmap_set_bits(data->regmap, JC42_REG_SMBUS,
++                                    SMBUS_STMOUT);
++              if (ret)
++                      return ret;
+       }
+-      config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG);
+-      if (config < 0)
+-              return config;
++      ret = regmap_read(data->regmap, JC42_REG_CONFIG, &config);
++      if (ret)
++              return ret;
+       data->orig_config = config;
+       if (config & JC42_CFG_SHUTDOWN) {
+               config &= ~JC42_CFG_SHUTDOWN;
+-              i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config);
++              regmap_write(data->regmap, JC42_REG_CONFIG, config);
+       }
+       data->config = config;
+@@ -523,7 +554,7 @@ static int jc42_remove(struct i2c_client *client)
+               config = (data->orig_config & ~JC42_CFG_HYST_MASK)
+                 | (data->config & JC42_CFG_HYST_MASK);
+-              i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config);
++              regmap_write(data->regmap, JC42_REG_CONFIG, config);
+       }
+       return 0;
+ }
+@@ -535,8 +566,7 @@ static int jc42_suspend(struct device *dev)
+       struct jc42_data *data = dev_get_drvdata(dev);
+       data->config |= JC42_CFG_SHUTDOWN;
+-      i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
+-                                   data->config);
++      regmap_write(data->regmap, JC42_REG_CONFIG, data->config);
+       return 0;
+ }
+@@ -545,8 +575,7 @@ static int jc42_resume(struct device *dev)
+       struct jc42_data *data = dev_get_drvdata(dev);
+       data->config &= ~JC42_CFG_SHUTDOWN;
+-      i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
+-                                   data->config);
++      regmap_write(data->regmap, JC42_REG_CONFIG, data->config);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/hwmon-jc42-restore-the-min-max-critical-temperatures.patch b/queue-5.10/hwmon-jc42-restore-the-min-max-critical-temperatures.patch
new file mode 100644 (file)
index 0000000..487e322
--- /dev/null
@@ -0,0 +1,86 @@
+From 87efae251264794971284e2cfb25ce00c1062eef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Oct 2022 23:31:57 +0200
+Subject: hwmon: (jc42) Restore the min/max/critical temperatures on resume
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+
+[ Upstream commit 084ed144c448fd5bc8ed5a58247153fbbfd115c3 ]
+
+The JC42 compatible thermal sensor on Kingston KSM32ES8/16ME DIMMs
+(using Micron E-Die) is an ST Microelectronics STTS2004 (manufacturer
+0x104a, device 0x2201). It does not keep the previously programmed
+minimum, maximum and critical temperatures after system suspend and
+resume (which is a shutdown / startup cycle for the JC42 temperature
+sensor). This results in an alarm on system resume because the hardware
+default for these values is 0°C (so any environment temperature greater
+than 0°C will trigger the alarm).
+
+Example before system suspend:
+  jc42-i2c-0-1a
+  Adapter: SMBus PIIX4 adapter port 0 at 0b00
+  temp1:        +34.8°C  (low  =  +0.0°C)
+                         (high = +85.0°C, hyst = +85.0°C)
+                         (crit = +95.0°C, hyst = +95.0°C)
+
+Example after system resume (without this change):
+  jc42-i2c-0-1a
+  Adapter: SMBus PIIX4 adapter port 0 at 0b00
+  temp1:        +34.8°C  (low  =  +0.0°C)             ALARM (HIGH, CRIT)
+                         (high =  +0.0°C, hyst =  +0.0°C)
+                         (crit =  +0.0°C, hyst =  +0.0°C)
+
+Apply the cached values from the JC42_REG_TEMP_UPPER,
+JC42_REG_TEMP_LOWER, JC42_REG_TEMP_CRITICAL and JC42_REG_SMBUS (where
+the SMBUS register is not related to this issue but a side-effect of
+using regcache_sync() during system resume with the previously
+cached/programmed values. This fixes the alarm due to the hardware
+defaults of 0°C because the previously applied limits (set by userspace)
+are re-applied on system resume.
+
+Fixes: 175c490c9e7f ("hwmon: (jc42) Add support for STTS2004 and AT30TSE004")
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://lore.kernel.org/r/20221023213157.11078-3-martin.blumenstingl@googlemail.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/jc42.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c
+index 9a2a062eb7b8..5240bfdfcf2e 100644
+--- a/drivers/hwmon/jc42.c
++++ b/drivers/hwmon/jc42.c
+@@ -567,6 +567,10 @@ static int jc42_suspend(struct device *dev)
+       data->config |= JC42_CFG_SHUTDOWN;
+       regmap_write(data->regmap, JC42_REG_CONFIG, data->config);
++
++      regcache_cache_only(data->regmap, true);
++      regcache_mark_dirty(data->regmap);
++
+       return 0;
+ }
+@@ -574,9 +578,13 @@ static int jc42_resume(struct device *dev)
+ {
+       struct jc42_data *data = dev_get_drvdata(dev);
++      regcache_cache_only(data->regmap, false);
++
+       data->config &= ~JC42_CFG_SHUTDOWN;
+       regmap_write(data->regmap, JC42_REG_CONFIG, data->config);
+-      return 0;
++
++      /* Restore cached register values to hardware */
++      return regcache_sync(data->regmap);
+ }
+ static const struct dev_pm_ops jc42_dev_pm_ops = {
+-- 
+2.35.1
+
diff --git a/queue-5.10/hwrng-amd-fix-pci-device-refcount-leak.patch b/queue-5.10/hwrng-amd-fix-pci-device-refcount-leak.patch
new file mode 100644 (file)
index 0000000..60c6efe
--- /dev/null
@@ -0,0 +1,76 @@
+From d0755f3ce39040ce692439951c2b83b8c79740bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 21:22:33 +0800
+Subject: hwrng: amd - Fix PCI device refcount leak
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit ecadb5b0111ea19fc7c240bb25d424a94471eb7d ]
+
+for_each_pci_dev() is implemented by pci_get_device(). The comment of
+pci_get_device() says that it will increase the reference count for the
+returned pci_dev and also decrease the reference count for the input
+pci_dev @from if it is not NULL.
+
+If we break for_each_pci_dev() loop with pdev not NULL, we need to call
+pci_dev_put() to decrease the reference count. Add the missing
+pci_dev_put() for the normal and error path.
+
+Fixes: 96d63c0297cc ("[PATCH] Add AMD HW RNG driver")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/amd-rng.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
+index 9959c762da2f..db3dd467194c 100644
+--- a/drivers/char/hw_random/amd-rng.c
++++ b/drivers/char/hw_random/amd-rng.c
+@@ -143,15 +143,19 @@ static int __init mod_init(void)
+ found:
+       err = pci_read_config_dword(pdev, 0x58, &pmbase);
+       if (err)
+-              return err;
++              goto put_dev;
+       pmbase &= 0x0000FF00;
+-      if (pmbase == 0)
+-              return -EIO;
++      if (pmbase == 0) {
++              err = -EIO;
++              goto put_dev;
++      }
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+-      if (!priv)
+-              return -ENOMEM;
++      if (!priv) {
++              err = -ENOMEM;
++              goto put_dev;
++      }
+       if (!request_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) {
+               dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n",
+@@ -185,6 +189,8 @@ static int __init mod_init(void)
+       release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE);
+ out:
+       kfree(priv);
++put_dev:
++      pci_dev_put(pdev);
+       return err;
+ }
+@@ -200,6 +206,8 @@ static void __exit mod_exit(void)
+       release_region(priv->pmbase + PMBASE_OFFSET, PMBASE_SIZE);
++      pci_dev_put(priv->pcidev);
++
+       kfree(priv);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/hwrng-geode-fix-pci-device-refcount-leak.patch b/queue-5.10/hwrng-geode-fix-pci-device-refcount-leak.patch
new file mode 100644 (file)
index 0000000..39ca58d
--- /dev/null
@@ -0,0 +1,115 @@
+From d10294dc1db8a78d42fce3406e1877665421368d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 21:22:34 +0800
+Subject: hwrng: geode - Fix PCI device refcount leak
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit 9f6ec8dc574efb7f4f3d7ee9cd59ae307e78f445 ]
+
+for_each_pci_dev() is implemented by pci_get_device(). The comment of
+pci_get_device() says that it will increase the reference count for the
+returned pci_dev and also decrease the reference count for the input
+pci_dev @from if it is not NULL.
+
+If we break for_each_pci_dev() loop with pdev not NULL, we need to call
+pci_dev_put() to decrease the reference count. We add a new struct
+'amd_geode_priv' to record pointer of the pci_dev and membase, and then
+add missing pci_dev_put() for the normal and error path.
+
+Fixes: ef5d862734b8 ("[PATCH] Add Geode HW RNG driver")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/geode-rng.c | 36 +++++++++++++++++++++++-------
+ 1 file changed, 28 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c
+index e1d421a36a13..207272979f23 100644
+--- a/drivers/char/hw_random/geode-rng.c
++++ b/drivers/char/hw_random/geode-rng.c
+@@ -51,6 +51,10 @@ static const struct pci_device_id pci_tbl[] = {
+ };
+ MODULE_DEVICE_TABLE(pci, pci_tbl);
++struct amd_geode_priv {
++      struct pci_dev *pcidev;
++      void __iomem *membase;
++};
+ static int geode_rng_data_read(struct hwrng *rng, u32 *data)
+ {
+@@ -90,6 +94,7 @@ static int __init mod_init(void)
+       const struct pci_device_id *ent;
+       void __iomem *mem;
+       unsigned long rng_base;
++      struct amd_geode_priv *priv;
+       for_each_pci_dev(pdev) {
+               ent = pci_match_id(pci_tbl, pdev);
+@@ -97,17 +102,26 @@ static int __init mod_init(void)
+                       goto found;
+       }
+       /* Device not found. */
+-      goto out;
++      return err;
+ found:
++      priv = kzalloc(sizeof(*priv), GFP_KERNEL);
++      if (!priv) {
++              err = -ENOMEM;
++              goto put_dev;
++      }
++
+       rng_base = pci_resource_start(pdev, 0);
+       if (rng_base == 0)
+-              goto out;
++              goto free_priv;
+       err = -ENOMEM;
+       mem = ioremap(rng_base, 0x58);
+       if (!mem)
+-              goto out;
+-      geode_rng.priv = (unsigned long)mem;
++              goto free_priv;
++
++      geode_rng.priv = (unsigned long)priv;
++      priv->membase = mem;
++      priv->pcidev = pdev;
+       pr_info("AMD Geode RNG detected\n");
+       err = hwrng_register(&geode_rng);
+@@ -116,20 +130,26 @@ static int __init mod_init(void)
+                      err);
+               goto err_unmap;
+       }
+-out:
+       return err;
+ err_unmap:
+       iounmap(mem);
+-      goto out;
++free_priv:
++      kfree(priv);
++put_dev:
++      pci_dev_put(pdev);
++      return err;
+ }
+ static void __exit mod_exit(void)
+ {
+-      void __iomem *mem = (void __iomem *)geode_rng.priv;
++      struct amd_geode_priv *priv;
++      priv = (struct amd_geode_priv *)geode_rng.priv;
+       hwrng_unregister(&geode_rng);
+-      iounmap(mem);
++      iounmap(priv->membase);
++      pci_dev_put(priv->pcidev);
++      kfree(priv);
+ }
+ module_init(mod_init);
+-- 
+2.35.1
+
diff --git a/queue-5.10/i2c-ismt-fix-an-out-of-bounds-bug-in-ismt_access.patch b/queue-5.10/i2c-ismt-fix-an-out-of-bounds-bug-in-ismt_access.patch
new file mode 100644 (file)
index 0000000..ad5cc34
--- /dev/null
@@ -0,0 +1,54 @@
+From 41bd034e8a61a98af5c91383c4223f309fdc5539 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Jul 2022 19:02:16 +0800
+Subject: i2c: ismt: Fix an out-of-bounds bug in ismt_access()
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit 39244cc754829bf707dccd12e2ce37510f5b1f8d ]
+
+When the driver does not check the data from the user, the variable
+'data->block[0]' may be very large to cause an out-of-bounds bug.
+
+The following log can reveal it:
+
+[   33.995542] i2c i2c-1: ioctl, cmd=0x720, arg=0x7ffcb3dc3a20
+[   33.995978] ismt_smbus 0000:00:05.0: I2C_SMBUS_BLOCK_DATA:  WRITE
+[   33.996475] ==================================================================
+[   33.996995] BUG: KASAN: out-of-bounds in ismt_access.cold+0x374/0x214b
+[   33.997473] Read of size 18446744073709551615 at addr ffff88810efcfdb1 by task ismt_poc/485
+[   33.999450] Call Trace:
+[   34.001849]  memcpy+0x20/0x60
+[   34.002077]  ismt_access.cold+0x374/0x214b
+[   34.003382]  __i2c_smbus_xfer+0x44f/0xfb0
+[   34.004007]  i2c_smbus_xfer+0x10a/0x390
+[   34.004291]  i2cdev_ioctl_smbus+0x2c8/0x710
+[   34.005196]  i2cdev_ioctl+0x5ec/0x74c
+
+Fix this bug by checking the size of 'data->block[0]' first.
+
+Fixes: 13f35ac14cd0 ("i2c: Adding support for Intel iSMT SMBus 2.0 host controller")
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-ismt.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
+index 3d2d92640651..cec2b2ae7684 100644
+--- a/drivers/i2c/busses/i2c-ismt.c
++++ b/drivers/i2c/busses/i2c-ismt.c
+@@ -507,6 +507,9 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
+               if (read_write == I2C_SMBUS_WRITE) {
+                       /* Block Write */
+                       dev_dbg(dev, "I2C_SMBUS_BLOCK_DATA:  WRITE\n");
++                      if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
++                              return -EINVAL;
++
+                       dma_size = data->block[0] + 1;
+                       dma_direction = DMA_TO_DEVICE;
+                       desc->wr_len_cmd = dma_size;
+-- 
+2.35.1
+
diff --git a/queue-5.10/i2c-mux-reg-check-return-value-after-calling-platfor.patch b/queue-5.10/i2c-mux-reg-check-return-value-after-calling-platfor.patch
new file mode 100644 (file)
index 0000000..f6dffb9
--- /dev/null
@@ -0,0 +1,46 @@
+From b9b215b633247e51391a7b92b848a9ec283d1137 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Oct 2022 17:38:25 +0800
+Subject: i2c: mux: reg: check return value after calling
+ platform_get_resource()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 2d47b79d2bd39cc6369eccf94a06568d84c906ae ]
+
+It will cause null-ptr-deref in resource_size(), if platform_get_resource()
+returns NULL, move calling resource_size() after devm_ioremap_resource() that
+will check 'res' to avoid null-ptr-deref.
+And use devm_platform_get_and_ioremap_resource() to simplify code.
+
+Fixes: b3fdd32799d8 ("i2c: mux: Add register-based mux i2c-mux-reg")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/muxes/i2c-mux-reg.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-reg.c
+index 0e0679f65cf7..30a6de1694e0 100644
+--- a/drivers/i2c/muxes/i2c-mux-reg.c
++++ b/drivers/i2c/muxes/i2c-mux-reg.c
+@@ -183,13 +183,12 @@ static int i2c_mux_reg_probe(struct platform_device *pdev)
+       if (!mux->data.reg) {
+               dev_info(&pdev->dev,
+                       "Register not set, using platform resource\n");
+-              res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-              mux->data.reg_size = resource_size(res);
+-              mux->data.reg = devm_ioremap_resource(&pdev->dev, res);
++              mux->data.reg = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+               if (IS_ERR(mux->data.reg)) {
+                       ret = PTR_ERR(mux->data.reg);
+                       goto err_put_parent;
+               }
++              mux->data.reg_size = resource_size(res);
+       }
+       if (mux->data.reg_size != 4 && mux->data.reg_size != 2 &&
+-- 
+2.35.1
+
diff --git a/queue-5.10/i2c-pxa-pci-fix-missing-pci_disable_device-on-error-.patch b/queue-5.10/i2c-pxa-pci-fix-missing-pci_disable_device-on-error-.patch
new file mode 100644 (file)
index 0000000..a6d6228
--- /dev/null
@@ -0,0 +1,58 @@
+From fa92c8e5281a09ffe2a971ce5c68e7de8361f987 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 17:25:40 +0800
+Subject: i2c: pxa-pci: fix missing pci_disable_device() on error in
+ ce4100_i2c_probe
+
+From: Hui Tang <tanghui20@huawei.com>
+
+[ Upstream commit d78a167332e1ca8113268ed922c1212fd71b73ad ]
+
+Using pcim_enable_device() to avoid missing pci_disable_device().
+
+Fixes: 7e94dd154e93 ("i2c-pxa2xx: Add PCI support for PXA I2C controller")
+Signed-off-by: Hui Tang <tanghui20@huawei.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-pxa-pci.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c
+index f614cade432b..30e38bc8b6db 100644
+--- a/drivers/i2c/busses/i2c-pxa-pci.c
++++ b/drivers/i2c/busses/i2c-pxa-pci.c
+@@ -105,7 +105,7 @@ static int ce4100_i2c_probe(struct pci_dev *dev,
+       int i;
+       struct ce4100_devices *sds;
+-      ret = pci_enable_device_mem(dev);
++      ret = pcim_enable_device(dev);
+       if (ret)
+               return ret;
+@@ -114,10 +114,8 @@ static int ce4100_i2c_probe(struct pci_dev *dev,
+               return -EINVAL;
+       }
+       sds = kzalloc(sizeof(*sds), GFP_KERNEL);
+-      if (!sds) {
+-              ret = -ENOMEM;
+-              goto err_mem;
+-      }
++      if (!sds)
++              return -ENOMEM;
+       for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) {
+               sds->pdev[i] = add_i2c_device(dev, i);
+@@ -133,8 +131,6 @@ static int ce4100_i2c_probe(struct pci_dev *dev,
+ err_dev_add:
+       kfree(sds);
+-err_mem:
+-      pci_disable_device(dev);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/ib-ipoib-fix-queue-count-inconsistency-for-pkey-chil.patch b/queue-5.10/ib-ipoib-fix-queue-count-inconsistency-for-pkey-chil.patch
new file mode 100644 (file)
index 0000000..52b1c0b
--- /dev/null
@@ -0,0 +1,61 @@
+From 65e9feb2a7997261de6442a5c50047c0d540718d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 09:52:54 +0200
+Subject: IB/IPoIB: Fix queue count inconsistency for PKEY child interfaces
+
+From: Dragos Tatulea <dtatulea@nvidia.com>
+
+[ Upstream commit dbc94a0fb81771a38733c0e8f2ea8c4fa6934dc1 ]
+
+There are 2 ways to create IPoIB PKEY child interfaces:
+1) Writing a PKEY to /sys/class/net/<ib parent interface>/create_child.
+2) Using netlink with iproute.
+
+While with sysfs the child interface has the same number of tx and
+rx queues as the parent, with netlink there will always be 1 tx
+and 1 rx queue for the child interface. That's because the
+get_num_tx/rx_queues() netlink ops are missing and the default value
+of 1 is taken for the number of queues (in rtnl_create_link()).
+
+This change adds the get_num_tx/rx_queues() ops which allows for
+interfaces with multiple queues to be created over netlink. This
+constant only represents the max number of tx and rx queues on that
+net device.
+
+Fixes: 9baa0b036410 ("IB/ipoib: Add rtnl_link_ops support")
+Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
+Link: https://lore.kernel.org/r/f4a42c8aa43c02d5ae5559a60c3e5e0f18c82531.1670485816.git.leonro@nvidia.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/ipoib/ipoib_netlink.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+index 5b05cf3837da..28e9b70844e4 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+@@ -42,6 +42,11 @@ static const struct nla_policy ipoib_policy[IFLA_IPOIB_MAX + 1] = {
+       [IFLA_IPOIB_UMCAST]     = { .type = NLA_U16 },
+ };
++static unsigned int ipoib_get_max_num_queues(void)
++{
++      return min_t(unsigned int, num_possible_cpus(), 128);
++}
++
+ static int ipoib_fill_info(struct sk_buff *skb, const struct net_device *dev)
+ {
+       struct ipoib_dev_priv *priv = ipoib_priv(dev);
+@@ -173,6 +178,8 @@ static struct rtnl_link_ops ipoib_link_ops __read_mostly = {
+       .changelink     = ipoib_changelink,
+       .get_size       = ipoib_get_size,
+       .fill_info      = ipoib_fill_info,
++      .get_num_rx_queues = ipoib_get_max_num_queues,
++      .get_num_tx_queues = ipoib_get_max_num_queues,
+ };
+ struct rtnl_link_ops *ipoib_get_link_ops(void)
+-- 
+2.35.1
+
diff --git a/queue-5.10/igb-do-not-free-q_vector-unless-new-one-was-allocate.patch b/queue-5.10/igb-do-not-free-q_vector-unless-new-one-was-allocate.patch
new file mode 100644 (file)
index 0000000..2e4ce56
--- /dev/null
@@ -0,0 +1,53 @@
+From 89291a02521b99ad4774b852b41b5a9d9aab02ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 02:25:24 -0700
+Subject: igb: Do not free q_vector unless new one was allocated
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 0668716506ca66f90d395f36ccdaebc3e0e84801 ]
+
+Avoid potential use-after-free condition under memory pressure. If the
+kzalloc() fails, q_vector will be freed but left in the original
+adapter->q_vector[v_idx] array position.
+
+Cc: Jesse Brandeburg <jesse.brandeburg@intel.com>
+Cc: Tony Nguyen <anthony.l.nguyen@intel.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: Paolo Abeni <pabeni@redhat.com>
+Cc: intel-wired-lan@lists.osuosl.org
+Cc: netdev@vger.kernel.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Gurucharan <gurucharanx.g@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igb/igb_main.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index 2646601c3487..0ea8e4024d63 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -1204,8 +1204,12 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
+       if (!q_vector) {
+               q_vector = kzalloc(size, GFP_KERNEL);
+       } else if (size > ksize(q_vector)) {
+-              kfree_rcu(q_vector, rcu);
+-              q_vector = kzalloc(size, GFP_KERNEL);
++              struct igb_q_vector *new_q_vector;
++
++              new_q_vector = kzalloc(size, GFP_KERNEL);
++              if (new_q_vector)
++                      kfree_rcu(q_vector, rcu);
++              q_vector = new_q_vector;
+       } else {
+               memset(q_vector, 0, size);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/igc-add-checking-for-basetime-less-than-zero.patch b/queue-5.10/igc-add-checking-for-basetime-less-than-zero.patch
new file mode 100644 (file)
index 0000000..b4fe079
--- /dev/null
@@ -0,0 +1,39 @@
+From 7c6729d420e206e302e976d073ce5e08362960d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 12:15:19 +0800
+Subject: igc: Add checking for basetime less than zero
+
+From: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
+
+[ Upstream commit 3b61764fb49a6e147ac90d71dccdddc9d5508ba1 ]
+
+Using the tc qdisc command, the user can set basetime to any value.
+Checking should be done on the driver's side to prevent registering
+basetime values that are less than zero.
+
+Fixes: ec50a9d437f0 ("igc: Add support for taprio offloading")
+Signed-off-by: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
+Tested-by: Naama Meir <naamax.meir@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index f4082ea7beaa..45069dc0ccc6 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -4912,6 +4912,9 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+               return 0;
+       }
++      if (qopt->base_time < 0)
++              return -ERANGE;
++
+       if (adapter->base_time)
+               return -EALREADY;
+-- 
+2.35.1
+
diff --git a/queue-5.10/igc-enhance-qbv-scheduling-by-using-first-flag-bit.patch b/queue-5.10/igc-enhance-qbv-scheduling-by-using-first-flag-bit.patch
new file mode 100644 (file)
index 0000000..733dc46
--- /dev/null
@@ -0,0 +1,431 @@
+From 94333ca3def03dd0ffef8707cf48a534c6697775 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 12:15:17 +0800
+Subject: igc: Enhance Qbv scheduling by using first flag bit
+
+From: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+
+[ Upstream commit db0b124f02ba68de6517ac303d431af220ccfe9f ]
+
+The I225 hardware has a limitation that packets can only be scheduled
+in the [0, cycle-time] interval. So, scheduling a packet to the start
+of the next cycle doesn't usually work.
+
+To overcome this, we use the Transmit Descriptor first flag to indicates
+that a packet should be the first packet (from a queue) in a cycle
+according to the section 7.5.2.9.3.4 The First Packet on Each QBV Cycle
+in Intel Discrete I225/6 User Manual.
+
+But this only works if there was any packet from that queue during the
+current cycle, to avoid this issue, we issue an empty packet if that's
+not the case. Also require one more descriptor to be available, to take
+into account the empty packet that might be issued.
+
+Test Setup:
+
+Talker: Use l2_tai to generate the launchtime into packet load.
+
+Listener: Use timedump.c to compute the delta between packet arrival
+and LaunchTime packet payload.
+
+Test Result:
+
+Before:
+
+1666000610127300000,1666000610127300096,96,621273
+1666000610127400000,1666000610127400192,192,621274
+1666000610127500000,1666000610127500032,32,621275
+1666000610127600000,1666000610127600128,128,621276
+1666000610127700000,1666000610127700224,224,621277
+1666000610127800000,1666000610127800064,64,621278
+1666000610127900000,1666000610127900160,160,621279
+1666000610128000000,1666000610128000000,0,621280
+1666000610128100000,1666000610128100096,96,621281
+1666000610128200000,1666000610128200192,192,621282
+1666000610128300000,1666000610128300032,32,621283
+1666000610128400000,1666000610128301056,-98944,621284
+1666000610128500000,1666000610128302080,-197920,621285
+1666000610128600000,1666000610128302848,-297152,621286
+1666000610128700000,1666000610128303872,-396128,621287
+1666000610128800000,1666000610128304896,-495104,621288
+1666000610128900000,1666000610128305664,-594336,621289
+1666000610129000000,1666000610128306688,-693312,621290
+1666000610129100000,1666000610128307712,-792288,621291
+1666000610129200000,1666000610128308480,-891520,621292
+1666000610129300000,1666000610128309504,-990496,621293
+1666000610129400000,1666000610128310528,-1089472,621294
+1666000610129500000,1666000610128311296,-1188704,621295
+1666000610129600000,1666000610128312320,-1287680,621296
+1666000610129700000,1666000610128313344,-1386656,621297
+1666000610129800000,1666000610128314112,-1485888,621298
+1666000610129900000,1666000610128315136,-1584864,621299
+1666000610130000000,1666000610128316160,-1683840,621300
+1666000610130100000,1666000610128316928,-1783072,621301
+1666000610130200000,1666000610128317952,-1882048,621302
+1666000610130300000,1666000610128318976,-1981024,621303
+1666000610130400000,1666000610128319744,-2080256,621304
+1666000610130500000,1666000610128320768,-2179232,621305
+1666000610130600000,1666000610128321792,-2278208,621306
+1666000610130700000,1666000610128322816,-2377184,621307
+1666000610130800000,1666000610128323584,-2476416,621308
+1666000610130900000,1666000610128324608,-2575392,621309
+1666000610131000000,1666000610128325632,-2674368,621310
+1666000610131100000,1666000610128326400,-2773600,621311
+1666000610131200000,1666000610128327424,-2872576,621312
+1666000610131300000,1666000610128328448,-2971552,621313
+1666000610131400000,1666000610128329216,-3070784,621314
+1666000610131500000,1666000610131500032,32,621315
+1666000610131600000,1666000610131600128,128,621316
+1666000610131700000,1666000610131700224,224,621317
+
+After:
+
+1666073510646200000,1666073510646200064,64,2676462
+1666073510646300000,1666073510646300160,160,2676463
+1666073510646400000,1666073510646400256,256,2676464
+1666073510646500000,1666073510646500096,96,2676465
+1666073510646600000,1666073510646600192,192,2676466
+1666073510646700000,1666073510646700032,32,2676467
+1666073510646800000,1666073510646800128,128,2676468
+1666073510646900000,1666073510646900224,224,2676469
+1666073510647000000,1666073510647000064,64,2676470
+1666073510647100000,1666073510647100160,160,2676471
+1666073510647200000,1666073510647200256,256,2676472
+1666073510647300000,1666073510647300096,96,2676473
+1666073510647400000,1666073510647400192,192,2676474
+1666073510647500000,1666073510647500032,32,2676475
+1666073510647600000,1666073510647600128,128,2676476
+1666073510647700000,1666073510647700224,224,2676477
+1666073510647800000,1666073510647800064,64,2676478
+1666073510647900000,1666073510647900160,160,2676479
+1666073510648000000,1666073510648000000,0,2676480
+1666073510648100000,1666073510648100096,96,2676481
+1666073510648200000,1666073510648200192,192,2676482
+1666073510648300000,1666073510648300032,32,2676483
+1666073510648400000,1666073510648400128,128,2676484
+1666073510648500000,1666073510648500224,224,2676485
+1666073510648600000,1666073510648600064,64,2676486
+1666073510648700000,1666073510648700160,160,2676487
+1666073510648800000,1666073510648800000,0,2676488
+1666073510648900000,1666073510648900096,96,2676489
+1666073510649000000,1666073510649000192,192,2676490
+1666073510649100000,1666073510649100032,32,2676491
+1666073510649200000,1666073510649200128,128,2676492
+1666073510649300000,1666073510649300224,224,2676493
+1666073510649400000,1666073510649400064,64,2676494
+1666073510649500000,1666073510649500160,160,2676495
+1666073510649600000,1666073510649600000,0,2676496
+1666073510649700000,1666073510649700096,96,2676497
+1666073510649800000,1666073510649800192,192,2676498
+1666073510649900000,1666073510649900032,32,2676499
+1666073510650000000,1666073510650000128,128,2676500
+
+Fixes: 82faa9b79950 ("igc: Add support for ETF offloading")
+Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Co-developed-by: Aravindhan Gunasekaran <aravindhan.gunasekaran@intel.com>
+Signed-off-by: Aravindhan Gunasekaran <aravindhan.gunasekaran@intel.com>
+Co-developed-by: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
+Signed-off-by: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
+Signed-off-by: Malli C <mallikarjuna.chilakala@intel.com>
+Tested-by: Naama Meir <naamax.meir@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc.h         |   2 +
+ drivers/net/ethernet/intel/igc/igc_defines.h |   2 +
+ drivers/net/ethernet/intel/igc/igc_main.c    | 176 ++++++++++++++++---
+ 3 files changed, 151 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
+index a97bf7a5f1d6..970dd878d8a7 100644
+--- a/drivers/net/ethernet/intel/igc/igc.h
++++ b/drivers/net/ethernet/intel/igc/igc.h
+@@ -87,6 +87,8 @@ struct igc_ring {
+       u8 queue_index;                 /* logical index of the ring*/
+       u8 reg_idx;                     /* physical index of the ring */
+       bool launchtime_enable;         /* true if LaunchTime is enabled */
++      ktime_t last_tx_cycle;          /* end of the cycle with a launchtime transmission */
++      ktime_t last_ff_cycle;          /* Last cycle with an active first flag */
+       u32 start_time;
+       u32 end_time;
+diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
+index 32f5fd684139..352b50d3881d 100644
+--- a/drivers/net/ethernet/intel/igc/igc_defines.h
++++ b/drivers/net/ethernet/intel/igc/igc_defines.h
+@@ -278,6 +278,8 @@
+ #define IGC_ADVTXD_L4LEN_SHIFT        8  /* Adv ctxt L4LEN shift */
+ #define IGC_ADVTXD_MSS_SHIFT  16 /* Adv ctxt MSS shift */
++#define IGC_ADVTXD_TSN_CNTX_FIRST     0x00000080
++
+ /* Transmit Control */
+ #define IGC_TCTL_EN           0x00000002 /* enable Tx */
+ #define IGC_TCTL_PSP          0x00000008 /* pad short packets */
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 48192594d3d7..f4082ea7beaa 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -898,25 +898,118 @@ static int igc_write_mc_addr_list(struct net_device *netdev)
+       return netdev_mc_count(netdev);
+ }
+-static __le32 igc_tx_launchtime(struct igc_adapter *adapter, ktime_t txtime)
++static __le32 igc_tx_launchtime(struct igc_ring *ring, ktime_t txtime,
++                              bool *first_flag, bool *insert_empty)
+ {
++      struct igc_adapter *adapter = netdev_priv(ring->netdev);
+       ktime_t cycle_time = adapter->cycle_time;
+       ktime_t base_time = adapter->base_time;
++      ktime_t now = ktime_get_clocktai();
++      ktime_t baset_est, end_of_cycle;
+       u32 launchtime;
++      s64 n;
+-      /* FIXME: when using ETF together with taprio, we may have a
+-       * case where 'delta' is larger than the cycle_time, this may
+-       * cause problems if we don't read the current value of
+-       * IGC_BASET, as the value writen into the launchtime
+-       * descriptor field may be misinterpreted.
++      n = div64_s64(ktime_sub_ns(now, base_time), cycle_time);
++
++      baset_est = ktime_add_ns(base_time, cycle_time * (n));
++      end_of_cycle = ktime_add_ns(baset_est, cycle_time);
++
++      if (ktime_compare(txtime, end_of_cycle) >= 0) {
++              if (baset_est != ring->last_ff_cycle) {
++                      *first_flag = true;
++                      ring->last_ff_cycle = baset_est;
++
++                      if (ktime_compare(txtime, ring->last_tx_cycle) > 0)
++                              *insert_empty = true;
++              }
++      }
++
++      /* Introducing a window at end of cycle on which packets
++       * potentially not honor launchtime. Window of 5us chosen
++       * considering software update the tail pointer and packets
++       * are dma'ed to packet buffer.
+        */
+-      div_s64_rem(ktime_sub_ns(txtime, base_time), cycle_time, &launchtime);
++      if ((ktime_sub_ns(end_of_cycle, now) < 5 * NSEC_PER_USEC))
++              netdev_warn(ring->netdev, "Packet with txtime=%llu may not be honoured\n",
++                          txtime);
++
++      ring->last_tx_cycle = end_of_cycle;
++
++      launchtime = ktime_sub_ns(txtime, baset_est);
++      if (launchtime > 0)
++              div_s64_rem(launchtime, cycle_time, &launchtime);
++      else
++              launchtime = 0;
+       return cpu_to_le32(launchtime);
+ }
++static int igc_init_empty_frame(struct igc_ring *ring,
++                              struct igc_tx_buffer *buffer,
++                              struct sk_buff *skb)
++{
++      unsigned int size;
++      dma_addr_t dma;
++
++      size = skb_headlen(skb);
++
++      dma = dma_map_single(ring->dev, skb->data, size, DMA_TO_DEVICE);
++      if (dma_mapping_error(ring->dev, dma)) {
++              netdev_err_once(ring->netdev, "Failed to map DMA for TX\n");
++              return -ENOMEM;
++      }
++
++      buffer->skb = skb;
++      buffer->protocol = 0;
++      buffer->bytecount = skb->len;
++      buffer->gso_segs = 1;
++      buffer->time_stamp = jiffies;
++      dma_unmap_len_set(buffer, len, skb->len);
++      dma_unmap_addr_set(buffer, dma, dma);
++
++      return 0;
++}
++
++static int igc_init_tx_empty_descriptor(struct igc_ring *ring,
++                                      struct sk_buff *skb,
++                                      struct igc_tx_buffer *first)
++{
++      union igc_adv_tx_desc *desc;
++      u32 cmd_type, olinfo_status;
++      int err;
++
++      if (!igc_desc_unused(ring))
++              return -EBUSY;
++
++      err = igc_init_empty_frame(ring, first, skb);
++      if (err)
++              return err;
++
++      cmd_type = IGC_ADVTXD_DTYP_DATA | IGC_ADVTXD_DCMD_DEXT |
++                 IGC_ADVTXD_DCMD_IFCS | IGC_TXD_DCMD |
++                 first->bytecount;
++      olinfo_status = first->bytecount << IGC_ADVTXD_PAYLEN_SHIFT;
++
++      desc = IGC_TX_DESC(ring, ring->next_to_use);
++      desc->read.cmd_type_len = cpu_to_le32(cmd_type);
++      desc->read.olinfo_status = cpu_to_le32(olinfo_status);
++      desc->read.buffer_addr = cpu_to_le64(dma_unmap_addr(first, dma));
++
++      netdev_tx_sent_queue(txring_txq(ring), skb->len);
++
++      first->next_to_watch = desc;
++
++      ring->next_to_use++;
++      if (ring->next_to_use == ring->count)
++              ring->next_to_use = 0;
++
++      return 0;
++}
++
++#define IGC_EMPTY_FRAME_SIZE 60
++
+ static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
+-                          struct igc_tx_buffer *first,
++                          __le32 launch_time, bool first_flag,
+                           u32 vlan_macip_lens, u32 type_tucmd,
+                           u32 mss_l4len_idx)
+ {
+@@ -935,26 +1028,17 @@ static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
+       if (test_bit(IGC_RING_FLAG_TX_CTX_IDX, &tx_ring->flags))
+               mss_l4len_idx |= tx_ring->reg_idx << 4;
++      if (first_flag)
++              mss_l4len_idx |= IGC_ADVTXD_TSN_CNTX_FIRST;
++
+       context_desc->vlan_macip_lens   = cpu_to_le32(vlan_macip_lens);
+       context_desc->type_tucmd_mlhl   = cpu_to_le32(type_tucmd);
+       context_desc->mss_l4len_idx     = cpu_to_le32(mss_l4len_idx);
+-
+-      /* We assume there is always a valid Tx time available. Invalid times
+-       * should have been handled by the upper layers.
+-       */
+-      if (tx_ring->launchtime_enable) {
+-              struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
+-              ktime_t txtime = first->skb->tstamp;
+-
+-              skb_txtime_consumed(first->skb);
+-              context_desc->launch_time = igc_tx_launchtime(adapter,
+-                                                            txtime);
+-      } else {
+-              context_desc->launch_time = 0;
+-      }
++      context_desc->launch_time       = launch_time;
+ }
+-static void igc_tx_csum(struct igc_ring *tx_ring, struct igc_tx_buffer *first)
++static void igc_tx_csum(struct igc_ring *tx_ring, struct igc_tx_buffer *first,
++                      __le32 launch_time, bool first_flag)
+ {
+       struct sk_buff *skb = first->skb;
+       u32 vlan_macip_lens = 0;
+@@ -994,7 +1078,8 @@ static void igc_tx_csum(struct igc_ring *tx_ring, struct igc_tx_buffer *first)
+       vlan_macip_lens |= skb_network_offset(skb) << IGC_ADVTXD_MACLEN_SHIFT;
+       vlan_macip_lens |= first->tx_flags & IGC_TX_FLAGS_VLAN_MASK;
+-      igc_tx_ctxtdesc(tx_ring, first, vlan_macip_lens, type_tucmd, 0);
++      igc_tx_ctxtdesc(tx_ring, launch_time, first_flag,
++                      vlan_macip_lens, type_tucmd, 0);
+ }
+ static int __igc_maybe_stop_tx(struct igc_ring *tx_ring, const u16 size)
+@@ -1218,6 +1303,7 @@ static int igc_tx_map(struct igc_ring *tx_ring,
+ static int igc_tso(struct igc_ring *tx_ring,
+                  struct igc_tx_buffer *first,
++                 __le32 launch_time, bool first_flag,
+                  u8 *hdr_len)
+ {
+       u32 vlan_macip_lens, type_tucmd, mss_l4len_idx;
+@@ -1304,8 +1390,8 @@ static int igc_tso(struct igc_ring *tx_ring,
+       vlan_macip_lens |= (ip.hdr - skb->data) << IGC_ADVTXD_MACLEN_SHIFT;
+       vlan_macip_lens |= first->tx_flags & IGC_TX_FLAGS_VLAN_MASK;
+-      igc_tx_ctxtdesc(tx_ring, first, vlan_macip_lens,
+-                      type_tucmd, mss_l4len_idx);
++      igc_tx_ctxtdesc(tx_ring, launch_time, first_flag,
++                      vlan_macip_lens, type_tucmd, mss_l4len_idx);
+       return 1;
+ }
+@@ -1313,11 +1399,14 @@ static int igc_tso(struct igc_ring *tx_ring,
+ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+                                      struct igc_ring *tx_ring)
+ {
++      bool first_flag = false, insert_empty = false;
+       u16 count = TXD_USE_COUNT(skb_headlen(skb));
+       __be16 protocol = vlan_get_protocol(skb);
+       struct igc_tx_buffer *first;
++      __le32 launch_time = 0;
+       u32 tx_flags = 0;
+       unsigned short f;
++      ktime_t txtime;
+       u8 hdr_len = 0;
+       int tso = 0;
+@@ -1331,11 +1420,40 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+               count += TXD_USE_COUNT(skb_frag_size(
+                                               &skb_shinfo(skb)->frags[f]));
+-      if (igc_maybe_stop_tx(tx_ring, count + 3)) {
++      if (igc_maybe_stop_tx(tx_ring, count + 5)) {
+               /* this is a hard error */
+               return NETDEV_TX_BUSY;
+       }
++      if (!tx_ring->launchtime_enable)
++              goto done;
++
++      txtime = skb->tstamp;
++      skb->tstamp = ktime_set(0, 0);
++      launch_time = igc_tx_launchtime(tx_ring, txtime, &first_flag, &insert_empty);
++
++      if (insert_empty) {
++              struct igc_tx_buffer *empty_info;
++              struct sk_buff *empty;
++              void *data;
++
++              empty_info = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
++              empty = alloc_skb(IGC_EMPTY_FRAME_SIZE, GFP_ATOMIC);
++              if (!empty)
++                      goto done;
++
++              data = skb_put(empty, IGC_EMPTY_FRAME_SIZE);
++              memset(data, 0, IGC_EMPTY_FRAME_SIZE);
++
++              igc_tx_ctxtdesc(tx_ring, 0, false, 0, 0, 0);
++
++              if (igc_init_tx_empty_descriptor(tx_ring,
++                                               empty,
++                                               empty_info) < 0)
++                      dev_kfree_skb_any(empty);
++      }
++
++done:
+       /* record the location of the first descriptor for this packet */
+       first = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
+       first->skb = skb;
+@@ -1366,11 +1484,11 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+       first->tx_flags = tx_flags;
+       first->protocol = protocol;
+-      tso = igc_tso(tx_ring, first, &hdr_len);
++      tso = igc_tso(tx_ring, first, launch_time, first_flag, &hdr_len);
+       if (tso < 0)
+               goto out_drop;
+       else if (!tso)
+-              igc_tx_csum(tx_ring, first);
++              igc_tx_csum(tx_ring, first, launch_time, first_flag);
+       igc_tx_map(tx_ring, first, hdr_len);
+-- 
+2.35.1
+
diff --git a/queue-5.10/igc-lift-taprio-schedule-restriction.patch b/queue-5.10/igc-lift-taprio-schedule-restriction.patch
new file mode 100644 (file)
index 0000000..52b20e9
--- /dev/null
@@ -0,0 +1,101 @@
+From 3cf5b27711f75bbbd90c24688d15c7563e441866 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 11:27:47 +0200
+Subject: igc: Lift TAPRIO schedule restriction
+
+From: Kurt Kanzenbach <kurt@linutronix.de>
+
+[ Upstream commit a5fd39464a4081ce11c801d7e20c4551ba7cb983 ]
+
+Add support for Qbv schedules where one queue stays open
+in consecutive entries. Currently that's not supported.
+
+Example schedule:
+
+|tc qdisc replace dev ${INTERFACE} handle 100 parent root taprio num_tc 3 \
+|   map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 \
+|   queues 1@0 1@1 2@2 \
+|   base-time ${BASETIME} \
+|   sched-entry S 0x01 300000 \ # Stream High/Low
+|   sched-entry S 0x06 500000 \ # Management and Best Effort
+|   sched-entry S 0x04 200000 \ # Best Effort
+|   flags 0x02
+
+Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
+Reviewed-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Tested-by: Naama Meir <naamax.meir@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: 72abeedd8398 ("igc: Set Qbv start_time and end_time to end_time if not being configured in GCL")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_main.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 94a608585f71..9420a169780c 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -4862,9 +4862,10 @@ static bool validate_schedule(struct igc_adapter *adapter,
+               return false;
+       for (n = 0; n < qopt->num_entries; n++) {
+-              const struct tc_taprio_sched_entry *e;
++              const struct tc_taprio_sched_entry *e, *prev;
+               int i;
++              prev = n ? &qopt->entries[n - 1] : NULL;
+               e = &qopt->entries[n];
+               /* i225 only supports "global" frame preemption
+@@ -4877,7 +4878,12 @@ static bool validate_schedule(struct igc_adapter *adapter,
+                       if (e->gate_mask & BIT(i))
+                               queue_uses[i]++;
+-                      if (queue_uses[i] > 1)
++                      /* There are limitations: A single queue cannot be
++                       * opened and closed multiple times per cycle unless the
++                       * gate stays open. Check for it.
++                       */
++                      if (queue_uses[i] > 1 &&
++                          !(prev->gate_mask & BIT(i)))
+                               return false;
+               }
+       }
+@@ -4904,6 +4910,7 @@ static int igc_tsn_enable_launchtime(struct igc_adapter *adapter,
+ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+                                struct tc_taprio_qopt_offload *qopt)
+ {
++      bool queue_configured[IGC_MAX_TX_QUEUES] = { };
+       u32 start_time = 0, end_time = 0;
+       size_t n;
+@@ -4924,9 +4931,6 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+       adapter->cycle_time = qopt->cycle_time;
+       adapter->base_time = qopt->base_time;
+-      /* FIXME: be a little smarter about cases when the gate for a
+-       * queue stays open for more than one entry.
+-       */
+       for (n = 0; n < qopt->num_entries; n++) {
+               struct tc_taprio_sched_entry *e = &qopt->entries[n];
+               int i;
+@@ -4954,8 +4958,15 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+                       if (!(e->gate_mask & BIT(i)))
+                               continue;
+-                      ring->start_time = start_time;
++                      /* Check whether a queue stays open for more than one
++                       * entry. If so, keep the start and advance the end
++                       * time.
++                       */
++                      if (!queue_configured[i])
++                              ring->start_time = start_time;
+                       ring->end_time = end_time;
++
++                      queue_configured[i] = true;
+               }
+               start_time += e->interval;
+-- 
+2.35.1
+
diff --git a/queue-5.10/igc-recalculate-qbv-end_time-by-considering-cycle-ti.patch b/queue-5.10/igc-recalculate-qbv-end_time-by-considering-cycle-ti.patch
new file mode 100644 (file)
index 0000000..ba7c05f
--- /dev/null
@@ -0,0 +1,57 @@
+From 746ce4135fa17f950ab61b23639d78b537aaf044 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 12:15:21 +0800
+Subject: igc: recalculate Qbv end_time by considering cycle time
+
+From: Tan Tee Min <tee.min.tan@linux.intel.com>
+
+[ Upstream commit 6d05251d537a4d3835959a8cdd8cbbbdcdc0c904 ]
+
+Qbv users can specify a cycle time that is not equal to the total GCL
+intervals. Hence, recalculation is necessary here to exclude the time
+interval that exceeds the cycle time. As those GCL which exceeds the
+cycle time will be truncated.
+
+According to IEEE Std. 802.1Q-2018 section 8.6.9.2, once the end of
+the list is reached, it will switch to the END_OF_CYCLE state and
+leave the gates in the same state until the next cycle is started.
+
+Fixes: ec50a9d437f0 ("igc: Add support for taprio offloading")
+Signed-off-by: Tan Tee Min <tee.min.tan@linux.intel.com>
+Signed-off-by: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
+Tested-by: Naama Meir <naamax.meir@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_main.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 45069dc0ccc6..94a608585f71 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -4933,6 +4933,21 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+               end_time += e->interval;
++              /* If any of the conditions below are true, we need to manually
++               * control the end time of the cycle.
++               * 1. Qbv users can specify a cycle time that is not equal
++               * to the total GCL intervals. Hence, recalculation is
++               * necessary here to exclude the time interval that
++               * exceeds the cycle time.
++               * 2. According to IEEE Std. 802.1Q-2018 section 8.6.9.2,
++               * once the end of the list is reached, it will switch
++               * to the END_OF_CYCLE state and leave the gates in the
++               * same state until the next cycle is started.
++               */
++              if (end_time > adapter->cycle_time ||
++                  n + 1 == qopt->num_entries)
++                      end_time = adapter->cycle_time;
++
+               for (i = 0; i < adapter->num_tx_queues; i++) {
+                       struct igc_ring *ring = adapter->tx_ring[i];
+-- 
+2.35.1
+
diff --git a/queue-5.10/igc-set-qbv-start_time-and-end_time-to-end_time-if-n.patch b/queue-5.10/igc-set-qbv-start_time-and-end_time-to-end_time-if-n.patch
new file mode 100644 (file)
index 0000000..87b0a01
--- /dev/null
@@ -0,0 +1,70 @@
+From 380596ed02ff365513bbe1c84dfd20b1865d2f03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 12:15:22 +0800
+Subject: igc: Set Qbv start_time and end_time to end_time if not being
+ configured in GCL
+
+From: Tan Tee Min <tee.min.tan@linux.intel.com>
+
+[ Upstream commit 72abeedd83982c1bc6023f631e412db78374d9b4 ]
+
+The default setting of end_time minus start_time is whole 1 second.
+Thus, if it's not being configured in any GCL entry then it will be
+staying at original 1 second.
+
+This patch is changing the start_time and end_time to be end_time as
+if setting zero will be having weird HW behavior where the gate will
+not be fully closed.
+
+Fixes: ec50a9d437f0 ("igc: Add support for taprio offloading")
+Signed-off-by: Tan Tee Min <tee.min.tan@linux.intel.com>
+Signed-off-by: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
+Tested-by: Naama Meir <naamax.meir@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_main.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 9420a169780c..1a0aae7b128d 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -4913,6 +4913,7 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+       bool queue_configured[IGC_MAX_TX_QUEUES] = { };
+       u32 start_time = 0, end_time = 0;
+       size_t n;
++      int i;
+       if (!qopt->enable) {
+               adapter->base_time = 0;
+@@ -4933,7 +4934,6 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+       for (n = 0; n < qopt->num_entries; n++) {
+               struct tc_taprio_sched_entry *e = &qopt->entries[n];
+-              int i;
+               end_time += e->interval;
+@@ -4972,6 +4972,18 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+               start_time += e->interval;
+       }
++      /* Check whether a queue gets configured.
++       * If not, set the start and end time to be end time.
++       */
++      for (i = 0; i < adapter->num_tx_queues; i++) {
++              if (!queue_configured[i]) {
++                      struct igc_ring *ring = adapter->tx_ring[i];
++
++                      ring->start_time = end_time;
++                      ring->end_time = end_time;
++              }
++      }
++
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/igc-use-strict-cycles-for-qbv-scheduling.patch b/queue-5.10/igc-use-strict-cycles-for-qbv-scheduling.patch
new file mode 100644 (file)
index 0000000..da2b82f
--- /dev/null
@@ -0,0 +1,52 @@
+From cf15e29da19d9a8d81e7edab50bdfc5d8e34f311 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 12:15:18 +0800
+Subject: igc: Use strict cycles for Qbv scheduling
+
+From: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+
+[ Upstream commit d8f45be01dd9381065a3778a579385249ed011dc ]
+
+Configuring strict cycle mode in the controller forces more well
+behaved transmissions when taprio is offloaded.
+
+When set this strict_cycle and strict_end, transmission is not
+enabled if the whole packet cannot be completed before end of
+the Qbv cycle.
+
+Fixes: 82faa9b79950 ("igc: Add support for ETF offloading")
+Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: Aravindhan Gunasekaran <aravindhan.gunasekaran@intel.com>
+Signed-off-by: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
+Tested-by: Naama Meir <naamax.meir@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_tsn.c | 11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c
+index 174103c4bea6..2d4db2a547b2 100644
+--- a/drivers/net/ethernet/intel/igc/igc_tsn.c
++++ b/drivers/net/ethernet/intel/igc/igc_tsn.c
+@@ -92,15 +92,8 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
+               wr32(IGC_STQT(i), ring->start_time);
+               wr32(IGC_ENDQT(i), ring->end_time);
+-              if (adapter->base_time) {
+-                      /* If we have a base_time we are in "taprio"
+-                       * mode and we need to be strict about the
+-                       * cycles: only transmit a packet if it can be
+-                       * completed during that cycle.
+-                       */
+-                      txqctl |= IGC_TXQCTL_STRICT_CYCLE |
+-                              IGC_TXQCTL_STRICT_END;
+-              }
++              txqctl |= IGC_TXQCTL_STRICT_CYCLE |
++                      IGC_TXQCTL_STRICT_END;
+               if (ring->launchtime_enable)
+                       txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
+-- 
+2.35.1
+
diff --git a/queue-5.10/iio-adis-add-__adis_enable_irq-implementation.patch b/queue-5.10/iio-adis-add-__adis_enable_irq-implementation.patch
new file mode 100644 (file)
index 0000000..7106eaf
--- /dev/null
@@ -0,0 +1,139 @@
+From 568bff9b6d3068fe23d401f52c2d3c6be3bc8e15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 10:27:49 +0200
+Subject: iio: adis: add '__adis_enable_irq()' implementation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ramona Bolboaca <ramona.bolboaca@analog.com>
+
+[ Upstream commit 99c05e4283a19a02a256f14100ca4ec3b2da3f62 ]
+
+Add '__adis_enable_irq()' implementation which is the unlocked
+version of 'adis_enable_irq()'.
+Call '__adis_enable_irq()' instead of 'adis_enable_irq()' from
+'__adis_intial_startup()' to keep the expected unlocked functionality.
+
+This fix is needed to remove a deadlock for all devices which are
+using 'adis_initial_startup()'. The deadlock occurs because the
+same mutex is acquired twice, without releasing it.
+The mutex is acquired once inside 'adis_initial_startup()', before
+calling '__adis_initial_startup()', and once inside
+'adis_enable_irq()', which is called by '__adis_initial_startup()'.
+The deadlock is removed by calling '__adis_enable_irq()', instead of
+'adis_enable_irq()' from within '__adis_initial_startup()'.
+
+Fixes: b600bd7eb3335 ("iio: adis: do not disabe IRQs in 'adis_init()'")
+Signed-off-by: Ramona Bolboaca <ramona.bolboaca@analog.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20221122082757.449452-2-ramona.bolboaca@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/adis.c       | 28 ++++++++++------------------
+ include/linux/iio/imu/adis.h | 13 ++++++++++++-
+ 2 files changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
+index b0a426053c20..e9821814afec 100644
+--- a/drivers/iio/imu/adis.c
++++ b/drivers/iio/imu/adis.c
+@@ -274,23 +274,19 @@ EXPORT_SYMBOL_NS(adis_debugfs_reg_access, IIO_ADISLIB);
+ #endif
+ /**
+- * adis_enable_irq() - Enable or disable data ready IRQ
++ * __adis_enable_irq() - Enable or disable data ready IRQ (unlocked)
+  * @adis: The adis device
+  * @enable: Whether to enable the IRQ
+  *
+  * Returns 0 on success, negative error code otherwise
+  */
+-int adis_enable_irq(struct adis *adis, bool enable)
++int __adis_enable_irq(struct adis *adis, bool enable)
+ {
+-      int ret = 0;
++      int ret;
+       u16 msc;
+-      mutex_lock(&adis->state_lock);
+-
+-      if (adis->data->enable_irq) {
+-              ret = adis->data->enable_irq(adis, enable);
+-              goto out_unlock;
+-      }
++      if (adis->data->enable_irq)
++              return adis->data->enable_irq(adis, enable);
+       if (adis->data->unmasked_drdy) {
+               if (enable)
+@@ -298,12 +294,12 @@ int adis_enable_irq(struct adis *adis, bool enable)
+               else
+                       disable_irq(adis->spi->irq);
+-              goto out_unlock;
++              return 0;
+       }
+       ret = __adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
+       if (ret)
+-              goto out_unlock;
++              return ret;
+       msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
+       msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
+@@ -312,13 +308,9 @@ int adis_enable_irq(struct adis *adis, bool enable)
+       else
+               msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
+-      ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
+-
+-out_unlock:
+-      mutex_unlock(&adis->state_lock);
+-      return ret;
++      return __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
+ }
+-EXPORT_SYMBOL_NS(adis_enable_irq, IIO_ADISLIB);
++EXPORT_SYMBOL_NS(__adis_enable_irq, IIO_ADISLIB);
+ /**
+  * __adis_check_status() - Check the device for error conditions (unlocked)
+@@ -449,7 +441,7 @@ int __adis_initial_startup(struct adis *adis)
+        * with 'IRQF_NO_AUTOEN' anyways.
+        */
+       if (!adis->data->unmasked_drdy)
+-              adis_enable_irq(adis, false);
++              __adis_enable_irq(adis, false);
+       if (!adis->data->prod_id_reg)
+               return 0;
+diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h
+index 1b66953573ee..5f45b785e794 100644
+--- a/include/linux/iio/imu/adis.h
++++ b/include/linux/iio/imu/adis.h
+@@ -404,9 +404,20 @@ static inline int adis_update_bits_base(struct adis *adis, unsigned int reg,
+               __adis_update_bits_base(adis, reg, mask, val, 2));      \
+ })
+-int adis_enable_irq(struct adis *adis, bool enable);
+ int __adis_check_status(struct adis *adis);
+ int __adis_initial_startup(struct adis *adis);
++int __adis_enable_irq(struct adis *adis, bool enable);
++
++static inline int adis_enable_irq(struct adis *adis, bool enable)
++{
++      int ret;
++
++      mutex_lock(&adis->state_lock);
++      ret = __adis_enable_irq(adis, enable);
++      mutex_unlock(&adis->state_lock);
++
++      return ret;
++}
+ static inline int adis_check_status(struct adis *adis)
+ {
+-- 
+2.35.1
+
diff --git a/queue-5.10/iio-adis-handle-devices-that-cannot-unmask-the-drdy-.patch b/queue-5.10/iio-adis-handle-devices-that-cannot-unmask-the-drdy-.patch
new file mode 100644 (file)
index 0000000..edf02dc
--- /dev/null
@@ -0,0 +1,105 @@
+From dbfe8b6ea453c78977e7b271de5f20b16a8339c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Sep 2021 16:14:20 +0200
+Subject: iio: adis: handle devices that cannot unmask the drdy pin
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nuno Sá <nuno.sa@analog.com>
+
+[ Upstream commit 31fa357ac809affd9f9a7d0b5d1991951e16beec ]
+
+Some devices can't mask/unmask the data ready pin and in those cases
+each driver was just calling '{dis}enable_irq()' to control the trigger
+state. This change, moves that handling into the library by introducing
+a new boolean in the data structure that tells the library that the
+device cannot unmask the pin.
+
+On top of controlling the trigger state, we can also use this flag to
+automatically request the IRQ with 'IRQF_NO_AUTOEN' in case it is set.
+So far, all users of the library want to start operation with IRQs/DRDY
+pin disabled so it should be fairly safe to do this inside the library.
+
+Signed-off-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210903141423.517028-3-nuno.sa@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 99c05e4283a1 ("iio: adis: add '__adis_enable_irq()' implementation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/adis.c         | 15 ++++++++++++++-
+ drivers/iio/imu/adis_trigger.c |  4 ++++
+ include/linux/iio/imu/adis.h   |  2 ++
+ 3 files changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
+index 715eef81bc24..5fcf269e98a6 100644
+--- a/drivers/iio/imu/adis.c
++++ b/drivers/iio/imu/adis.c
+@@ -290,6 +290,13 @@ int adis_enable_irq(struct adis *adis, bool enable)
+       if (adis->data->enable_irq) {
+               ret = adis->data->enable_irq(adis, enable);
+               goto out_unlock;
++      } else if (adis->data->unmasked_drdy) {
++              if (enable)
++                      enable_irq(adis->spi->irq);
++              else
++                      disable_irq(adis->spi->irq);
++
++              goto out_unlock;
+       }
+       ret = __adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
+@@ -434,7 +441,13 @@ int __adis_initial_startup(struct adis *adis)
+       if (ret)
+               return ret;
+-      adis_enable_irq(adis, false);
++      /*
++       * don't bother calling this if we can't unmask the IRQ as in this case
++       * the IRQ is most likely not yet requested and we will request it
++       * with 'IRQF_NO_AUTOEN' anyways.
++       */
++      if (!adis->data->unmasked_drdy)
++              adis_enable_irq(adis, false);
+       if (!adis->data->prod_id_reg)
+               return 0;
+diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c
+index 17058ac7aa9f..76b0488ef41b 100644
+--- a/drivers/iio/imu/adis_trigger.c
++++ b/drivers/iio/imu/adis_trigger.c
+@@ -37,6 +37,10 @@ static void adis_trigger_setup(struct adis *adis)
+ static int adis_validate_irq_flag(struct adis *adis)
+ {
+       unsigned long direction = adis->irq_flag & IRQF_TRIGGER_MASK;
++
++      /* We cannot mask the interrupt so ensure it's not enabled at request */
++      if (adis->data->unmasked_drdy)
++              adis->irq_flag |= IRQF_NO_AUTOEN;
+       /*
+        * Typically this devices have data ready either on the rising edge or
+        * on the falling edge of the data ready pin. This checks enforces that
+diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h
+index 04e96d688ba9..2ced0c88f481 100644
+--- a/include/linux/iio/imu/adis.h
++++ b/include/linux/iio/imu/adis.h
+@@ -49,6 +49,7 @@ struct adis_timeout {
+  * @status_error_mask: Bitmask of errors supported by the device
+  * @timeouts: Chip specific delays
+  * @enable_irq: Hook for ADIS devices that have a special IRQ enable/disable
++ * @unmasked_drdy: True for devices that cannot mask/unmask the data ready pin
+  * @has_paging: True if ADIS device has paged registers
+  * @burst_reg_cmd:    Register command that triggers burst
+  * @burst_len:                Burst size in the SPI RX buffer. If @burst_max_len is defined,
+@@ -77,6 +78,7 @@ struct adis_data {
+       unsigned int status_error_mask;
+       int (*enable_irq)(struct adis *adis, bool enable);
++      bool unmasked_drdy;
+       bool has_paging;
+-- 
+2.35.1
+
diff --git a/queue-5.10/iio-adis-stylistic-changes.patch b/queue-5.10/iio-adis-stylistic-changes.patch
new file mode 100644 (file)
index 0000000..2d38852
--- /dev/null
@@ -0,0 +1,434 @@
+From c61c53e1ab594120369b15ca4aa7e8f6df66930a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Jan 2022 14:09:05 +0100
+Subject: iio: adis: stylistic changes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nuno Sá <nuno.sa@analog.com>
+
+[ Upstream commit c39010ea6ba13bdf0003bd353e1d4c663aaac0a8 ]
+
+Minor stylistic changes to address checkptach complains when called with
+'--strict'.
+
+Signed-off-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220122130905.99-3-nuno.sa@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 99c05e4283a1 ("iio: adis: add '__adis_enable_irq()' implementation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/adis.c         | 47 +++++++++++++++++----------------
+ drivers/iio/imu/adis_buffer.c  |  6 ++---
+ drivers/iio/imu/adis_trigger.c |  3 +--
+ include/linux/iio/imu/adis.h   | 48 ++++++++++++++++++----------------
+ 4 files changed, 54 insertions(+), 50 deletions(-)
+
+diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
+index 5fcf269e98a6..54d1084f13d0 100644
+--- a/drivers/iio/imu/adis.c
++++ b/drivers/iio/imu/adis.c
+@@ -34,8 +34,8 @@
+  * @value: The value to write to device (up to 4 bytes)
+  * @size: The size of the @value (in bytes)
+  */
+-int __adis_write_reg(struct adis *adis, unsigned int reg,
+-      unsigned int value, unsigned int size)
++int __adis_write_reg(struct adis *adis, unsigned int reg, unsigned int value,
++                   unsigned int size)
+ {
+       unsigned int page = reg / ADIS_PAGE_SIZE;
+       int ret, i;
+@@ -118,7 +118,7 @@ int __adis_write_reg(struct adis *adis, unsigned int reg,
+       ret = spi_sync(adis->spi, &msg);
+       if (ret) {
+               dev_err(&adis->spi->dev, "Failed to write register 0x%02X: %d\n",
+-                              reg, ret);
++                      reg, ret);
+       } else {
+               adis->current_page = page;
+       }
+@@ -134,8 +134,8 @@ EXPORT_SYMBOL_GPL(__adis_write_reg);
+  * @val: The value read back from the device
+  * @size: The size of the @val buffer
+  */
+-int __adis_read_reg(struct adis *adis, unsigned int reg,
+-      unsigned int *val, unsigned int size)
++int __adis_read_reg(struct adis *adis, unsigned int reg, unsigned int *val,
++                  unsigned int size)
+ {
+       unsigned int page = reg / ADIS_PAGE_SIZE;
+       struct spi_message msg;
+@@ -205,12 +205,12 @@ int __adis_read_reg(struct adis *adis, unsigned int reg,
+       ret = spi_sync(adis->spi, &msg);
+       if (ret) {
+               dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n",
+-                              reg, ret);
++                      reg, ret);
+               return ret;
+-      } else {
+-              adis->current_page = page;
+       }
++      adis->current_page = page;
++
+       switch (size) {
+       case 4:
+               *val = get_unaligned_be32(adis->rx);
+@@ -251,13 +251,13 @@ EXPORT_SYMBOL_GPL(__adis_update_bits_base);
+ #ifdef CONFIG_DEBUG_FS
+-int adis_debugfs_reg_access(struct iio_dev *indio_dev,
+-      unsigned int reg, unsigned int writeval, unsigned int *readval)
++int adis_debugfs_reg_access(struct iio_dev *indio_dev, unsigned int reg,
++                          unsigned int writeval, unsigned int *readval)
+ {
+       struct adis *adis = iio_device_get_drvdata(indio_dev);
+       if (readval) {
+-              uint16_t val16;
++              u16 val16;
+               int ret;
+               ret = adis_read_reg_16(adis, reg, &val16);
+@@ -265,9 +265,9 @@ int adis_debugfs_reg_access(struct iio_dev *indio_dev,
+                       *readval = val16;
+               return ret;
+-      } else {
+-              return adis_write_reg_16(adis, reg, writeval);
+       }
++
++      return adis_write_reg_16(adis, reg, writeval);
+ }
+ EXPORT_SYMBOL(adis_debugfs_reg_access);
+@@ -283,14 +283,16 @@ EXPORT_SYMBOL(adis_debugfs_reg_access);
+ int adis_enable_irq(struct adis *adis, bool enable)
+ {
+       int ret = 0;
+-      uint16_t msc;
++      u16 msc;
+       mutex_lock(&adis->state_lock);
+       if (adis->data->enable_irq) {
+               ret = adis->data->enable_irq(adis, enable);
+               goto out_unlock;
+-      } else if (adis->data->unmasked_drdy) {
++      }
++
++      if (adis->data->unmasked_drdy) {
+               if (enable)
+                       enable_irq(adis->spi->irq);
+               else
+@@ -326,7 +328,7 @@ EXPORT_SYMBOL(adis_enable_irq);
+  */
+ int __adis_check_status(struct adis *adis)
+ {
+-      uint16_t status;
++      u16 status;
+       int ret;
+       int i;
+@@ -362,7 +364,7 @@ int __adis_reset(struct adis *adis)
+       const struct adis_timeout *timeouts = adis->data->timeouts;
+       ret = __adis_write_reg_8(adis, adis->data->glob_cmd_reg,
+-                      ADIS_GLOB_CMD_SW_RESET);
++                               ADIS_GLOB_CMD_SW_RESET);
+       if (ret) {
+               dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
+               return ret;
+@@ -418,7 +420,7 @@ int __adis_initial_startup(struct adis *adis)
+ {
+       const struct adis_timeout *timeouts = adis->data->timeouts;
+       struct gpio_desc *gpio;
+-      uint16_t prod_id;
++      u16 prod_id;
+       int ret;
+       /* check if the device has rst pin low */
+@@ -427,7 +429,7 @@ int __adis_initial_startup(struct adis *adis)
+               return PTR_ERR(gpio);
+       if (gpio) {
+-              msleep(10);
++              usleep_range(10, 12);
+               /* bring device out of reset */
+               gpiod_set_value_cansleep(gpio, 0);
+               msleep(timeouts->reset_ms);
+@@ -481,7 +483,8 @@ EXPORT_SYMBOL_GPL(__adis_initial_startup);
+  * a error bit in the channels raw value set error_mask to 0.
+  */
+ int adis_single_conversion(struct iio_dev *indio_dev,
+-      const struct iio_chan_spec *chan, unsigned int error_mask, int *val)
++                         const struct iio_chan_spec *chan,
++                         unsigned int error_mask, int *val)
+ {
+       struct adis *adis = iio_device_get_drvdata(indio_dev);
+       unsigned int uval;
+@@ -490,7 +493,7 @@ int adis_single_conversion(struct iio_dev *indio_dev,
+       mutex_lock(&adis->state_lock);
+       ret = __adis_read_reg(adis, chan->address, &uval,
+-                      chan->scan_type.storagebits / 8);
++                            chan->scan_type.storagebits / 8);
+       if (ret)
+               goto err_unlock;
+@@ -525,7 +528,7 @@ EXPORT_SYMBOL_GPL(adis_single_conversion);
+  * called.
+  */
+ int adis_init(struct adis *adis, struct iio_dev *indio_dev,
+-      struct spi_device *spi, const struct adis_data *data)
++            struct spi_device *spi, const struct adis_data *data)
+ {
+       if (!data || !data->timeouts) {
+               dev_err(&spi->dev, "No config data or timeouts not defined!\n");
+diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c
+index 175af154e443..7a7747617fca 100644
+--- a/drivers/iio/imu/adis_buffer.c
++++ b/drivers/iio/imu/adis_buffer.c
+@@ -20,7 +20,7 @@
+ #include <linux/iio/imu/adis.h>
+ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev,
+-      const unsigned long *scan_mask)
++                                     const unsigned long *scan_mask)
+ {
+       struct adis *adis = iio_device_get_drvdata(indio_dev);
+       unsigned int burst_length, burst_max_length;
+@@ -63,7 +63,7 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev,
+ }
+ int adis_update_scan_mode(struct iio_dev *indio_dev,
+-      const unsigned long *scan_mask)
++                        const unsigned long *scan_mask)
+ {
+       struct adis *adis = iio_device_get_drvdata(indio_dev);
+       const struct iio_chan_spec *chan;
+@@ -149,7 +149,7 @@ static irqreturn_t adis_trigger_handler(int irq, void *p)
+       }
+       iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
+-              pf->timestamp);
++                                         pf->timestamp);
+       iio_trigger_notify_done(indio_dev->trig);
+diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c
+index 76b0488ef41b..e7f0ee3e7a07 100644
+--- a/drivers/iio/imu/adis_trigger.c
++++ b/drivers/iio/imu/adis_trigger.c
+@@ -15,8 +15,7 @@
+ #include <linux/iio/trigger.h>
+ #include <linux/iio/imu/adis.h>
+-static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig,
+-                                              bool state)
++static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig, bool state)
+ {
+       struct adis *adis = iio_trigger_get_drvdata(trig);
+diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h
+index 2ced0c88f481..1b66953573ee 100644
+--- a/include/linux/iio/imu/adis.h
++++ b/include/linux/iio/imu/adis.h
+@@ -32,6 +32,7 @@ struct adis_timeout {
+       u16 sw_reset_ms;
+       u16 self_test_ms;
+ };
++
+ /**
+  * struct adis_data - ADIS chip variant specific data
+  * @read_delay: SPI delay for read operations in us
+@@ -45,7 +46,7 @@ struct adis_timeout {
+  * @self_test_mask: Bitmask of supported self-test operations
+  * @self_test_reg: Register address to request self test command
+  * @self_test_no_autoclear: True if device's self-test needs clear of ctrl reg
+- * @status_error_msgs: Array of error messgaes
++ * @status_error_msgs: Array of error messages
+  * @status_error_mask: Bitmask of errors supported by the device
+  * @timeouts: Chip specific delays
+  * @enable_irq: Hook for ADIS devices that have a special IRQ enable/disable
+@@ -128,12 +129,12 @@ struct adis {
+       unsigned long           irq_flag;
+       void                    *buffer;
+-      uint8_t                 tx[10] ____cacheline_aligned;
+-      uint8_t                 rx[4];
++      u8                      tx[10] ____cacheline_aligned;
++      u8                      rx[4];
+ };
+ int adis_init(struct adis *adis, struct iio_dev *indio_dev,
+-      struct spi_device *spi, const struct adis_data *data);
++            struct spi_device *spi, const struct adis_data *data);
+ int __adis_reset(struct adis *adis);
+ /**
+@@ -154,9 +155,9 @@ static inline int adis_reset(struct adis *adis)
+ }
+ int __adis_write_reg(struct adis *adis, unsigned int reg,
+-      unsigned int val, unsigned int size);
++                   unsigned int val, unsigned int size);
+ int __adis_read_reg(struct adis *adis, unsigned int reg,
+-      unsigned int *val, unsigned int size);
++                  unsigned int *val, unsigned int size);
+ /**
+  * __adis_write_reg_8() - Write single byte to a register (unlocked)
+@@ -165,7 +166,7 @@ int __adis_read_reg(struct adis *adis, unsigned int reg,
+  * @value: The value to write
+  */
+ static inline int __adis_write_reg_8(struct adis *adis, unsigned int reg,
+-      uint8_t val)
++                                   u8 val)
+ {
+       return __adis_write_reg(adis, reg, val, 1);
+ }
+@@ -177,7 +178,7 @@ static inline int __adis_write_reg_8(struct adis *adis, unsigned int reg,
+  * @value: Value to be written
+  */
+ static inline int __adis_write_reg_16(struct adis *adis, unsigned int reg,
+-      uint16_t val)
++                                    u16 val)
+ {
+       return __adis_write_reg(adis, reg, val, 2);
+ }
+@@ -189,7 +190,7 @@ static inline int __adis_write_reg_16(struct adis *adis, unsigned int reg,
+  * @value: Value to be written
+  */
+ static inline int __adis_write_reg_32(struct adis *adis, unsigned int reg,
+-      uint32_t val)
++                                    u32 val)
+ {
+       return __adis_write_reg(adis, reg, val, 4);
+ }
+@@ -201,7 +202,7 @@ static inline int __adis_write_reg_32(struct adis *adis, unsigned int reg,
+  * @val: The value read back from the device
+  */
+ static inline int __adis_read_reg_16(struct adis *adis, unsigned int reg,
+-      uint16_t *val)
++                                   u16 *val)
+ {
+       unsigned int tmp;
+       int ret;
+@@ -220,7 +221,7 @@ static inline int __adis_read_reg_16(struct adis *adis, unsigned int reg,
+  * @val: The value read back from the device
+  */
+ static inline int __adis_read_reg_32(struct adis *adis, unsigned int reg,
+-      uint32_t *val)
++                                   u32 *val)
+ {
+       unsigned int tmp;
+       int ret;
+@@ -240,7 +241,7 @@ static inline int __adis_read_reg_32(struct adis *adis, unsigned int reg,
+  * @size: The size of the @value (in bytes)
+  */
+ static inline int adis_write_reg(struct adis *adis, unsigned int reg,
+-      unsigned int val, unsigned int size)
++                               unsigned int val, unsigned int size)
+ {
+       int ret;
+@@ -259,7 +260,7 @@ static inline int adis_write_reg(struct adis *adis, unsigned int reg,
+  * @size: The size of the @val buffer
+  */
+ static int adis_read_reg(struct adis *adis, unsigned int reg,
+-      unsigned int *val, unsigned int size)
++                       unsigned int *val, unsigned int size)
+ {
+       int ret;
+@@ -277,7 +278,7 @@ static int adis_read_reg(struct adis *adis, unsigned int reg,
+  * @value: The value to write
+  */
+ static inline int adis_write_reg_8(struct adis *adis, unsigned int reg,
+-      uint8_t val)
++                                 u8 val)
+ {
+       return adis_write_reg(adis, reg, val, 1);
+ }
+@@ -289,7 +290,7 @@ static inline int adis_write_reg_8(struct adis *adis, unsigned int reg,
+  * @value: Value to be written
+  */
+ static inline int adis_write_reg_16(struct adis *adis, unsigned int reg,
+-      uint16_t val)
++                                  u16 val)
+ {
+       return adis_write_reg(adis, reg, val, 2);
+ }
+@@ -301,7 +302,7 @@ static inline int adis_write_reg_16(struct adis *adis, unsigned int reg,
+  * @value: Value to be written
+  */
+ static inline int adis_write_reg_32(struct adis *adis, unsigned int reg,
+-      uint32_t val)
++                                  u32 val)
+ {
+       return adis_write_reg(adis, reg, val, 4);
+ }
+@@ -313,7 +314,7 @@ static inline int adis_write_reg_32(struct adis *adis, unsigned int reg,
+  * @val: The value read back from the device
+  */
+ static inline int adis_read_reg_16(struct adis *adis, unsigned int reg,
+-      uint16_t *val)
++                                 u16 *val)
+ {
+       unsigned int tmp;
+       int ret;
+@@ -332,7 +333,7 @@ static inline int adis_read_reg_16(struct adis *adis, unsigned int reg,
+  * @val: The value read back from the device
+  */
+ static inline int adis_read_reg_32(struct adis *adis, unsigned int reg,
+-      uint32_t *val)
++                                 u32 *val)
+ {
+       unsigned int tmp;
+       int ret;
+@@ -431,8 +432,8 @@ static inline int adis_initial_startup(struct adis *adis)
+ }
+ int adis_single_conversion(struct iio_dev *indio_dev,
+-      const struct iio_chan_spec *chan, unsigned int error_mask,
+-      int *val);
++                         const struct iio_chan_spec *chan,
++                         unsigned int error_mask, int *val);
+ #define ADIS_VOLTAGE_CHAN(addr, si, chan, name, info_all, bits) { \
+       .type = IIO_VOLTAGE, \
+@@ -481,7 +482,7 @@ int adis_single_conversion(struct iio_dev *indio_dev,
+       .modified = 1, \
+       .channel2 = IIO_MOD_ ## mod, \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+-               info_sep, \
++               (info_sep), \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+       .info_mask_shared_by_all = info_all, \
+       .address = (addr), \
+@@ -515,7 +516,7 @@ devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
+ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev);
+ int adis_update_scan_mode(struct iio_dev *indio_dev,
+-      const unsigned long *scan_mask);
++                        const unsigned long *scan_mask);
+ #else /* CONFIG_IIO_BUFFER */
+@@ -539,7 +540,8 @@ static inline int devm_adis_probe_trigger(struct adis *adis,
+ #ifdef CONFIG_DEBUG_FS
+ int adis_debugfs_reg_access(struct iio_dev *indio_dev,
+-      unsigned int reg, unsigned int writeval, unsigned int *readval);
++                          unsigned int reg, unsigned int writeval,
++                          unsigned int *readval);
+ #else
+-- 
+2.35.1
+
diff --git a/queue-5.10/iio-imu-adis-move-exports-into-iio_adislib-namespace.patch b/queue-5.10/iio-imu-adis-move-exports-into-iio_adislib-namespace.patch
new file mode 100644 (file)
index 0000000..571bf6c
--- /dev/null
@@ -0,0 +1,254 @@
+From 919a293e542479f9ba79eb8540a4b30503700d91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Jan 2022 20:56:53 +0000
+Subject: iio:imu:adis: Move exports into IIO_ADISLIB namespace
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 6c9304d6af122f9afea41885ad82ed627e9442a8 ]
+
+In order to avoid unneessary pollution of the global symbol namespace
+move the common/library functions into a specific namespace and import
+that into the various specific device drivers that use them.
+
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Cc: Song Bao Hua (Barry Song) <song.bao.hua@hisilicon.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20220130205701.334592-9-jic23@kernel.org
+Stable-dep-of: 99c05e4283a1 ("iio: adis: add '__adis_enable_irq()' implementation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/adis16201.c         |  1 +
+ drivers/iio/accel/adis16209.c         |  1 +
+ drivers/iio/gyro/adis16136.c          |  1 +
+ drivers/iio/gyro/adis16260.c          |  1 +
+ drivers/iio/imu/adis.c                | 20 ++++++++++----------
+ drivers/iio/imu/adis16400.c           |  1 +
+ drivers/iio/imu/adis16460.c           |  1 +
+ drivers/iio/imu/adis16475.c           |  1 +
+ drivers/iio/imu/adis16480.c           |  1 +
+ drivers/iio/imu/adis_buffer.c         |  4 ++--
+ drivers/iio/imu/adis_trigger.c        |  2 +-
+ drivers/staging/iio/accel/adis16203.c |  1 +
+ drivers/staging/iio/accel/adis16240.c |  1 +
+ 13 files changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/iio/accel/adis16201.c b/drivers/iio/accel/adis16201.c
+index 84bbdfd2f2ba..b4ae4f86da3e 100644
+--- a/drivers/iio/accel/adis16201.c
++++ b/drivers/iio/accel/adis16201.c
+@@ -304,3 +304,4 @@ MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+ MODULE_DESCRIPTION("Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer");
+ MODULE_LICENSE("GPL v2");
+ MODULE_ALIAS("spi:adis16201");
++MODULE_IMPORT_NS(IIO_ADISLIB);
+diff --git a/drivers/iio/accel/adis16209.c b/drivers/iio/accel/adis16209.c
+index 4a841aec6268..e6e465f397d9 100644
+--- a/drivers/iio/accel/adis16209.c
++++ b/drivers/iio/accel/adis16209.c
+@@ -314,3 +314,4 @@ MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+ MODULE_DESCRIPTION("Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer");
+ MODULE_LICENSE("GPL v2");
+ MODULE_ALIAS("spi:adis16209");
++MODULE_IMPORT_NS(IIO_ADISLIB);
+diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c
+index a11ae9db0d11..74db8edb4283 100644
+--- a/drivers/iio/gyro/adis16136.c
++++ b/drivers/iio/gyro/adis16136.c
+@@ -599,3 +599,4 @@ module_spi_driver(adis16136_driver);
+ MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+ MODULE_DESCRIPTION("Analog Devices ADIS16133/ADIS16135/ADIS16136 gyroscope driver");
+ MODULE_LICENSE("GPL v2");
++MODULE_IMPORT_NS(IIO_ADISLIB);
+diff --git a/drivers/iio/gyro/adis16260.c b/drivers/iio/gyro/adis16260.c
+index e7c9a3e31c45..1e45d93de5b7 100644
+--- a/drivers/iio/gyro/adis16260.c
++++ b/drivers/iio/gyro/adis16260.c
+@@ -438,3 +438,4 @@ module_spi_driver(adis16260_driver);
+ MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+ MODULE_DESCRIPTION("Analog Devices ADIS16260/5 Digital Gyroscope Sensor");
+ MODULE_LICENSE("GPL v2");
++MODULE_IMPORT_NS(IIO_ADISLIB);
+diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
+index 54d1084f13d0..b0a426053c20 100644
+--- a/drivers/iio/imu/adis.c
++++ b/drivers/iio/imu/adis.c
+@@ -125,7 +125,7 @@ int __adis_write_reg(struct adis *adis, unsigned int reg, unsigned int value,
+       return ret;
+ }
+-EXPORT_SYMBOL_GPL(__adis_write_reg);
++EXPORT_SYMBOL_NS_GPL(__adis_write_reg, IIO_ADISLIB);
+ /**
+  * __adis_read_reg() - read N bytes from register (unlocked version)
+@@ -222,7 +222,7 @@ int __adis_read_reg(struct adis *adis, unsigned int reg, unsigned int *val,
+       return ret;
+ }
+-EXPORT_SYMBOL_GPL(__adis_read_reg);
++EXPORT_SYMBOL_NS_GPL(__adis_read_reg, IIO_ADISLIB);
+ /**
+  * __adis_update_bits_base() - ADIS Update bits function - Unlocked version
+  * @adis: The adis device
+@@ -247,7 +247,7 @@ int __adis_update_bits_base(struct adis *adis, unsigned int reg, const u32 mask,
+       return __adis_write_reg(adis, reg, __val, size);
+ }
+-EXPORT_SYMBOL_GPL(__adis_update_bits_base);
++EXPORT_SYMBOL_NS_GPL(__adis_update_bits_base, IIO_ADISLIB);
+ #ifdef CONFIG_DEBUG_FS
+@@ -269,7 +269,7 @@ int adis_debugfs_reg_access(struct iio_dev *indio_dev, unsigned int reg,
+       return adis_write_reg_16(adis, reg, writeval);
+ }
+-EXPORT_SYMBOL(adis_debugfs_reg_access);
++EXPORT_SYMBOL_NS(adis_debugfs_reg_access, IIO_ADISLIB);
+ #endif
+@@ -318,7 +318,7 @@ int adis_enable_irq(struct adis *adis, bool enable)
+       mutex_unlock(&adis->state_lock);
+       return ret;
+ }
+-EXPORT_SYMBOL(adis_enable_irq);
++EXPORT_SYMBOL_NS(adis_enable_irq, IIO_ADISLIB);
+ /**
+  * __adis_check_status() - Check the device for error conditions (unlocked)
+@@ -350,7 +350,7 @@ int __adis_check_status(struct adis *adis)
+       return -EIO;
+ }
+-EXPORT_SYMBOL_GPL(__adis_check_status);
++EXPORT_SYMBOL_NS_GPL(__adis_check_status, IIO_ADISLIB);
+ /**
+  * __adis_reset() - Reset the device (unlocked version)
+@@ -374,7 +374,7 @@ int __adis_reset(struct adis *adis)
+       return 0;
+ }
+-EXPORT_SYMBOL_GPL(__adis_reset);
++EXPORT_SYMBOL_NS_GPL(__adis_reset, IIO_ADIS_LIB);
+ static int adis_self_test(struct adis *adis)
+ {
+@@ -465,7 +465,7 @@ int __adis_initial_startup(struct adis *adis)
+       return 0;
+ }
+-EXPORT_SYMBOL_GPL(__adis_initial_startup);
++EXPORT_SYMBOL_NS_GPL(__adis_initial_startup, IIO_ADISLIB);
+ /**
+  * adis_single_conversion() - Performs a single sample conversion
+@@ -513,7 +513,7 @@ int adis_single_conversion(struct iio_dev *indio_dev,
+       mutex_unlock(&adis->state_lock);
+       return ret;
+ }
+-EXPORT_SYMBOL_GPL(adis_single_conversion);
++EXPORT_SYMBOL_NS_GPL(adis_single_conversion, IIO_ADISLIB);
+ /**
+  * adis_init() - Initialize adis device structure
+@@ -550,7 +550,7 @@ int adis_init(struct adis *adis, struct iio_dev *indio_dev,
+       return 0;
+ }
+-EXPORT_SYMBOL_GPL(adis_init);
++EXPORT_SYMBOL_NS_GPL(adis_init, IIO_ADISLIB);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c
+index 4aff16466da0..c5255116954a 100644
+--- a/drivers/iio/imu/adis16400.c
++++ b/drivers/iio/imu/adis16400.c
+@@ -1252,3 +1252,4 @@ module_spi_driver(adis16400_driver);
+ MODULE_AUTHOR("Manuel Stahl <manuel.stahl@iis.fraunhofer.de>");
+ MODULE_DESCRIPTION("Analog Devices ADIS16400/5 IMU SPI driver");
+ MODULE_LICENSE("GPL v2");
++MODULE_IMPORT_NS(IIO_ADISLIB);
+diff --git a/drivers/iio/imu/adis16460.c b/drivers/iio/imu/adis16460.c
+index 73bf45e859b8..a28143a19d3a 100644
+--- a/drivers/iio/imu/adis16460.c
++++ b/drivers/iio/imu/adis16460.c
+@@ -447,3 +447,4 @@ module_spi_driver(adis16460_driver);
+ MODULE_AUTHOR("Dragos Bogdan <dragos.bogdan@analog.com>");
+ MODULE_DESCRIPTION("Analog Devices ADIS16460 IMU driver");
+ MODULE_LICENSE("GPL");
++MODULE_IMPORT_NS(IIO_ADISLIB);
+diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c
+index 8ab88ba4892c..aed1cf3bfa13 100644
+--- a/drivers/iio/imu/adis16475.c
++++ b/drivers/iio/imu/adis16475.c
+@@ -1324,3 +1324,4 @@ module_spi_driver(adis16475_driver);
+ MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
+ MODULE_DESCRIPTION("Analog Devices ADIS16475 IMU driver");
+ MODULE_LICENSE("GPL");
++MODULE_IMPORT_NS(IIO_ADISLIB);
+diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c
+index dfe86c589325..c6a3d9a04fce 100644
+--- a/drivers/iio/imu/adis16480.c
++++ b/drivers/iio/imu/adis16480.c
+@@ -1340,3 +1340,4 @@ module_spi_driver(adis16480_driver);
+ MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+ MODULE_DESCRIPTION("Analog Devices ADIS16480 IMU driver");
+ MODULE_LICENSE("GPL v2");
++MODULE_IMPORT_NS(IIO_ADISLIB);
+diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c
+index 7a7747617fca..7cc1145910f6 100644
+--- a/drivers/iio/imu/adis_buffer.c
++++ b/drivers/iio/imu/adis_buffer.c
+@@ -120,7 +120,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev,
+       return 0;
+ }
+-EXPORT_SYMBOL_GPL(adis_update_scan_mode);
++EXPORT_SYMBOL_NS_GPL(adis_update_scan_mode, IIO_ADISLIB);
+ static irqreturn_t adis_trigger_handler(int irq, void *p)
+ {
+@@ -202,5 +202,5 @@ devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
+       return devm_add_action_or_reset(&adis->spi->dev, adis_buffer_cleanup,
+                                       adis);
+ }
+-EXPORT_SYMBOL_GPL(devm_adis_setup_buffer_and_trigger);
++EXPORT_SYMBOL_NS_GPL(devm_adis_setup_buffer_and_trigger, IIO_ADISLIB);
+diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c
+index e7f0ee3e7a07..80adfa58e50c 100644
+--- a/drivers/iio/imu/adis_trigger.c
++++ b/drivers/iio/imu/adis_trigger.c
+@@ -92,5 +92,5 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
+       return devm_iio_trigger_register(&adis->spi->dev, adis->trig);
+ }
+-EXPORT_SYMBOL_GPL(devm_adis_probe_trigger);
++EXPORT_SYMBOL_NS_GPL(devm_adis_probe_trigger, IIO_ADISLIB);
+diff --git a/drivers/staging/iio/accel/adis16203.c b/drivers/staging/iio/accel/adis16203.c
+index b68304da288b..7be44ff2c943 100644
+--- a/drivers/staging/iio/accel/adis16203.c
++++ b/drivers/staging/iio/accel/adis16203.c
+@@ -318,3 +318,4 @@ MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+ MODULE_DESCRIPTION("Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer");
+ MODULE_LICENSE("GPL v2");
+ MODULE_ALIAS("spi:adis16203");
++MODULE_IMPORT_NS(IIO_ADISLIB);
+diff --git a/drivers/staging/iio/accel/adis16240.c b/drivers/staging/iio/accel/adis16240.c
+index 5064adce5f58..dbbbf81207f9 100644
+--- a/drivers/staging/iio/accel/adis16240.c
++++ b/drivers/staging/iio/accel/adis16240.c
+@@ -445,3 +445,4 @@ MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+ MODULE_DESCRIPTION("Analog Devices Programmable Impact Sensor and Recorder");
+ MODULE_LICENSE("GPL v2");
+ MODULE_ALIAS("spi:adis16240");
++MODULE_IMPORT_NS(IIO_ADISLIB);
+-- 
+2.35.1
+
diff --git a/queue-5.10/iio-imu-adis-use-irqf_no_autoen-instead-of-irq-reque.patch b/queue-5.10/iio-imu-adis-use-irqf_no_autoen-instead-of-irq-reque.patch
new file mode 100644 (file)
index 0000000..a3553fc
--- /dev/null
@@ -0,0 +1,108 @@
+From b7eddbb1af136a9812c9e8a85a1abb8d6ea88aaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Apr 2021 19:45:43 +0100
+Subject: iio:imu:adis: Use IRQF_NO_AUTOEN instead of irq request then disable
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 30f6a542b7d39b1ba990a28a3891bc03691d8d41 ]
+
+This is a bit involved as the adis library code already has some
+sanity checking of the flags of the requested irq that we need
+to ensure is happy to pass through the IRQF_NO_AUTOEN flag untouched.
+
+Using this flag avoids us autoenabling the irq in the adis16460 and
+adis16475 drivers which cover parts that don't have any means of
+masking the interrupt on the device end.
+
+Note, compile tested only!
+
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Alexandru Ardelean <ardeleanalex@gmail.com>
+Reviewed-by: Nuno Sa <nuno.sa@analog.com>
+Reviewed-by: Barry Song <song.bao.hua@hisilicon.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
+Link: https://lore.kernel.org/r/20210402184544.488862-7-jic23@kernel.org
+Stable-dep-of: 99c05e4283a1 ("iio: adis: add '__adis_enable_irq()' implementation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/adis16460.c    |  4 ++--
+ drivers/iio/imu/adis16475.c    |  5 +++--
+ drivers/iio/imu/adis_trigger.c | 11 ++++++-----
+ 3 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/iio/imu/adis16460.c b/drivers/iio/imu/adis16460.c
+index 74a161e39733..73bf45e859b8 100644
+--- a/drivers/iio/imu/adis16460.c
++++ b/drivers/iio/imu/adis16460.c
+@@ -403,12 +403,12 @@ static int adis16460_probe(struct spi_device *spi)
+       if (ret)
+               return ret;
++      /* We cannot mask the interrupt, so ensure it isn't auto enabled */
++      st->adis.irq_flag |= IRQF_NO_AUTOEN;
+       ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
+       if (ret)
+               return ret;
+-      adis16460_enable_irq(&st->adis, 0);
+-
+       ret = __adis_initial_startup(&st->adis);
+       if (ret)
+               return ret;
+diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c
+index 3c4e4deb8760..8ab88ba4892c 100644
+--- a/drivers/iio/imu/adis16475.c
++++ b/drivers/iio/imu/adis16475.c
+@@ -1196,6 +1196,9 @@ static int adis16475_config_irq_pin(struct adis16475 *st)
+               return -EINVAL;
+       }
++      /* We cannot mask the interrupt so ensure it's not enabled at request */
++      st->adis.irq_flag |= IRQF_NO_AUTOEN;
++
+       val = ADIS16475_MSG_CTRL_DR_POL(polarity);
+       ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
+                                ADIS16475_MSG_CTRL_DR_POL_MASK, val);
+@@ -1300,8 +1303,6 @@ static int adis16475_probe(struct spi_device *spi)
+       if (ret)
+               return ret;
+-      adis16475_enable_irq(&st->adis, false);
+-
+       ret = devm_iio_device_register(&spi->dev, indio_dev);
+       if (ret)
+               return ret;
+diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c
+index 64e0ba51cb18..17058ac7aa9f 100644
+--- a/drivers/iio/imu/adis_trigger.c
++++ b/drivers/iio/imu/adis_trigger.c
+@@ -36,18 +36,19 @@ static void adis_trigger_setup(struct adis *adis)
+ static int adis_validate_irq_flag(struct adis *adis)
+ {
++      unsigned long direction = adis->irq_flag & IRQF_TRIGGER_MASK;
+       /*
+        * Typically this devices have data ready either on the rising edge or
+        * on the falling edge of the data ready pin. This checks enforces that
+        * one of those is set in the drivers... It defaults to
+-       * IRQF_TRIGGER_RISING for backward compatibility wiht devices that
++       * IRQF_TRIGGER_RISING for backward compatibility with devices that
+        * don't support changing the pin polarity.
+        */
+-      if (!adis->irq_flag) {
+-              adis->irq_flag = IRQF_TRIGGER_RISING;
++      if (direction == IRQF_TRIGGER_NONE) {
++              adis->irq_flag |= IRQF_TRIGGER_RISING;
+               return 0;
+-      } else if (adis->irq_flag != IRQF_TRIGGER_RISING &&
+-                 adis->irq_flag != IRQF_TRIGGER_FALLING) {
++      } else if (direction != IRQF_TRIGGER_RISING &&
++                 direction != IRQF_TRIGGER_FALLING) {
+               dev_err(&adis->spi->dev, "Invalid IRQ mask: %08lx\n",
+                       adis->irq_flag);
+               return -EINVAL;
+-- 
+2.35.1
+
diff --git a/queue-5.10/iio-temperature-ltc2983-make-bulk-write-buffer-dma-s.patch b/queue-5.10/iio-temperature-ltc2983-make-bulk-write-buffer-dma-s.patch
new file mode 100644 (file)
index 0000000..4cd1016
--- /dev/null
@@ -0,0 +1,61 @@
+From e8c2295d64a6659cf815ef2080996696f7563210 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Nov 2022 15:00:29 +0200
+Subject: iio: temperature: ltc2983: make bulk write buffer DMA-safe
+
+From: Cosmin Tanislav <cosmin.tanislav@analog.com>
+
+[ Upstream commit 5e0176213949724fbe9a8e4a39817edce337b8a0 ]
+
+regmap_bulk_write() does not guarantee implicit DMA-safety,
+even though the current implementation duplicates the given
+buffer. Do not rely on it.
+
+Fixes: f110f3188e56 ("iio: temperature: Add support for LTC2983")
+Signed-off-by: Cosmin Tanislav <cosmin.tanislav@analog.com>
+Link: https://lore.kernel.org/r/20221103130041.2153295-2-demonsingur@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/temperature/ltc2983.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
+index 8306daa77908..b2ae2d2c7eef 100644
+--- a/drivers/iio/temperature/ltc2983.c
++++ b/drivers/iio/temperature/ltc2983.c
+@@ -205,6 +205,7 @@ struct ltc2983_data {
+        * Holds the converted temperature
+        */
+       __be32 temp ____cacheline_aligned;
++      __be32 chan_val;
+ };
+ struct ltc2983_sensor {
+@@ -309,19 +310,18 @@ static int __ltc2983_fault_handler(const struct ltc2983_data *st,
+       return 0;
+ }
+-static int __ltc2983_chan_assign_common(const struct ltc2983_data *st,
++static int __ltc2983_chan_assign_common(struct ltc2983_data *st,
+                                       const struct ltc2983_sensor *sensor,
+                                       u32 chan_val)
+ {
+       u32 reg = LTC2983_CHAN_START_ADDR(sensor->chan);
+-      __be32 __chan_val;
+       chan_val |= LTC2983_CHAN_TYPE(sensor->type);
+       dev_dbg(&st->spi->dev, "Assign reg:0x%04X, val:0x%08X\n", reg,
+               chan_val);
+-      __chan_val = cpu_to_be32(chan_val);
+-      return regmap_bulk_write(st->regmap, reg, &__chan_val,
+-                               sizeof(__chan_val));
++      st->chan_val = cpu_to_be32(chan_val);
++      return regmap_bulk_write(st->regmap, reg, &st->chan_val,
++                               sizeof(st->chan_val));
+ }
+ static int __ltc2983_chan_custom_sensor_assign(struct ltc2983_data *st,
+-- 
+2.35.1
+
diff --git a/queue-5.10/ima-fix-fall-through-warnings-for-clang.patch b/queue-5.10/ima-fix-fall-through-warnings-for-clang.patch
new file mode 100644 (file)
index 0000000..f16a7d3
--- /dev/null
@@ -0,0 +1,58 @@
+From bf62257b07791c200208d84fd0e4c6d23f6d92dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Nov 2020 12:25:46 -0600
+Subject: ima: Fix fall-through warnings for Clang
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 28073eb09c5aa29e879490edb88cfd3e7073821e ]
+
+In preparation to enable -Wimplicit-fallthrough for Clang, fix multiple
+warnings by explicitly adding multiple break statements instead of just
+letting the code fall through to the next case.
+
+Link: https://github.com/KSPP/linux/issues/115
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Stable-dep-of: c7423dbdbc9e ("ima: Handle -ESTALE returned by ima_filter_rule_match()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/ima_main.c   | 1 +
+ security/integrity/ima/ima_policy.c | 2 ++
+ 2 files changed, 3 insertions(+)
+
+diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
+index 2d1af8899cab..600b97677085 100644
+--- a/security/integrity/ima/ima_main.c
++++ b/security/integrity/ima/ima_main.c
+@@ -743,6 +743,7 @@ int ima_load_data(enum kernel_load_data_id id, bool contents)
+                       pr_err("impossible to appraise a module without a file descriptor. sig_enforce kernel parameter might help\n");
+                       return -EACCES; /* INTEGRITY_UNKNOWN */
+               }
++              break;
+       default:
+               break;
+       }
+diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
+index 18569adcb4fe..4c937ff2e4dd 100644
+--- a/security/integrity/ima/ima_policy.c
++++ b/security/integrity/ima/ima_policy.c
+@@ -566,6 +566,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
+                       rc = ima_filter_rule_match(secid, rule->lsm[i].type,
+                                                  Audit_equal,
+                                                  rule->lsm[i].rule);
++                      break;
+               default:
+                       break;
+               }
+@@ -802,6 +803,7 @@ void __init ima_init_policy(void)
+               add_rules(default_measurement_rules,
+                         ARRAY_SIZE(default_measurement_rules),
+                         IMA_DEFAULT_POLICY);
++              break;
+       default:
+               break;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/ima-fix-misuse-of-dereference-of-pointer-in-template.patch b/queue-5.10/ima-fix-misuse-of-dereference-of-pointer-in-template.patch
new file mode 100644 (file)
index 0000000..27a516d
--- /dev/null
@@ -0,0 +1,47 @@
+From e65090f2e651c360e8faa8e0693216930567edda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Nov 2022 17:27:19 +0800
+Subject: ima: Fix misuse of dereference of pointer in
+ template_desc_init_fields()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 25369175ce84813dd99d6604e710dc2491f68523 ]
+
+The input parameter @fields is type of struct ima_template_field ***, so
+when allocates array memory for @fields, the size of element should be
+sizeof(**field) instead of sizeof(*field).
+
+Actually the original code would not cause any runtime error, but it's
+better to make it logically right.
+
+Fixes: adf53a778a0a ("ima: new templates management mechanism")
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Reviewed-by: Roberto Sassu <roberto.sassu@huawei.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/ima_template.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
+index f64c01d53e96..e053c741997b 100644
+--- a/security/integrity/ima/ima_template.c
++++ b/security/integrity/ima/ima_template.c
+@@ -220,11 +220,11 @@ int template_desc_init_fields(const char *template_fmt,
+       }
+       if (fields && num_fields) {
+-              *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL);
++              *fields = kmalloc_array(i, sizeof(**fields), GFP_KERNEL);
+               if (*fields == NULL)
+                       return -ENOMEM;
+-              memcpy(*fields, found_fields, i * sizeof(*fields));
++              memcpy(*fields, found_fields, i * sizeof(**fields));
+               *num_fields = i;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/ima-handle-estale-returned-by-ima_filter_rule_match.patch b/queue-5.10/ima-handle-estale-returned-by-ima_filter_rule_match.patch
new file mode 100644 (file)
index 0000000..a381e85
--- /dev/null
@@ -0,0 +1,114 @@
+From 02d76f15e0f23e6d8a1e8a826d0536c2e6dc8d11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Sep 2022 20:58:04 +0800
+Subject: ima: Handle -ESTALE returned by ima_filter_rule_match()
+
+From: GUO Zihua <guozihua@huawei.com>
+
+[ Upstream commit c7423dbdbc9ecef7fff5239d144cad4b9887f4de ]
+
+IMA relies on the blocking LSM policy notifier callback to update the
+LSM based IMA policy rules.
+
+When SELinux update its policies, IMA would be notified and starts
+updating all its lsm rules one-by-one. During this time, -ESTALE would
+be returned by ima_filter_rule_match() if it is called with a LSM rule
+that has not yet been updated. In ima_match_rules(), -ESTALE is not
+handled, and the LSM rule is considered a match, causing extra files
+to be measured by IMA.
+
+Fix it by re-initializing a temporary rule if -ESTALE is returned by
+ima_filter_rule_match(). The origin rule in the rule list would be
+updated by the LSM policy notifier callback.
+
+Fixes: b16942455193 ("ima: use the lsm policy update notifier")
+Signed-off-by: GUO Zihua <guozihua@huawei.com>
+Reviewed-by: Roberto Sassu <roberto.sassu@huawei.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/ima_policy.c | 41 ++++++++++++++++++++++-------
+ 1 file changed, 32 insertions(+), 9 deletions(-)
+
+diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
+index 4c937ff2e4dd..a83ce111cf50 100644
+--- a/security/integrity/ima/ima_policy.c
++++ b/security/integrity/ima/ima_policy.c
+@@ -503,6 +503,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
+                           const char *keyring)
+ {
+       int i;
++      bool result = false;
++      struct ima_rule_entry *lsm_rule = rule;
++      bool rule_reinitialized = false;
+       if (func == KEY_CHECK) {
+               return (rule->flags & IMA_FUNC) && (rule->func == func) &&
+@@ -545,35 +548,55 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
+               int rc = 0;
+               u32 osid;
+-              if (!rule->lsm[i].rule) {
+-                      if (!rule->lsm[i].args_p)
++              if (!lsm_rule->lsm[i].rule) {
++                      if (!lsm_rule->lsm[i].args_p)
+                               continue;
+                       else
+                               return false;
+               }
++
++retry:
+               switch (i) {
+               case LSM_OBJ_USER:
+               case LSM_OBJ_ROLE:
+               case LSM_OBJ_TYPE:
+                       security_inode_getsecid(inode, &osid);
+-                      rc = ima_filter_rule_match(osid, rule->lsm[i].type,
++                      rc = ima_filter_rule_match(osid, lsm_rule->lsm[i].type,
+                                                  Audit_equal,
+-                                                 rule->lsm[i].rule);
++                                                 lsm_rule->lsm[i].rule);
+                       break;
+               case LSM_SUBJ_USER:
+               case LSM_SUBJ_ROLE:
+               case LSM_SUBJ_TYPE:
+-                      rc = ima_filter_rule_match(secid, rule->lsm[i].type,
++                      rc = ima_filter_rule_match(secid, lsm_rule->lsm[i].type,
+                                                  Audit_equal,
+-                                                 rule->lsm[i].rule);
++                                                 lsm_rule->lsm[i].rule);
+                       break;
+               default:
+                       break;
+               }
+-              if (!rc)
+-                      return false;
++
++              if (rc == -ESTALE && !rule_reinitialized) {
++                      lsm_rule = ima_lsm_copy_rule(rule);
++                      if (lsm_rule) {
++                              rule_reinitialized = true;
++                              goto retry;
++                      }
++              }
++              if (!rc) {
++                      result = false;
++                      goto out;
++              }
+       }
+-      return true;
++      result = true;
++
++out:
++      if (rule_reinitialized) {
++              for (i = 0; i < MAX_LSM_RULES; i++)
++                      ima_filter_rule_free(lsm_rule->lsm[i].rule);
++              kfree(lsm_rule);
++      }
++      return result;
+ }
+ /*
+-- 
+2.35.1
+
diff --git a/queue-5.10/include-uapi-linux-swab-fix-potentially-missing-__al.patch b/queue-5.10/include-uapi-linux-swab-fix-potentially-missing-__al.patch
new file mode 100644 (file)
index 0000000..93d98af
--- /dev/null
@@ -0,0 +1,64 @@
+From 73b583c85c5fa118ba38e55363f2ec5bfda23362 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Sep 2022 14:52:56 -0700
+Subject: include/uapi/linux/swab: Fix potentially missing __always_inline
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matt Redfearn <matt.redfearn@mips.com>
+
+[ Upstream commit defbab270d45e32b068e7e73c3567232d745c60f ]
+
+Commit bc27fb68aaad ("include/uapi/linux/byteorder, swab: force inlining
+of some byteswap operations") added __always_inline to swab functions
+and commit 283d75737837 ("uapi/linux/stddef.h: Provide __always_inline to
+userspace headers") added a definition of __always_inline for use in
+exported headers when the kernel's compiler.h is not available.
+
+However, since swab.h does not include stddef.h, if the header soup does
+not indirectly include it, the definition of __always_inline is missing,
+resulting in a compilation failure, which was observed compiling the
+perf tool using exported headers containing this commit:
+
+In file included from /usr/include/linux/byteorder/little_endian.h:12:0,
+                 from /usr/include/asm/byteorder.h:14,
+                 from tools/include/uapi/linux/perf_event.h:20,
+                 from perf.h:8,
+                 from builtin-bench.c:18:
+/usr/include/linux/swab.h:160:8: error: unknown type name `__always_inline'
+ static __always_inline __u16 __swab16p(const __u16 *p)
+
+Fix this by replacing the inclusion of linux/compiler.h with
+linux/stddef.h to ensure that we pick up that definition if required,
+without relying on it's indirect inclusion. compiler.h is then included
+indirectly, via stddef.h.
+
+Fixes: 283d75737837 ("uapi/linux/stddef.h: Provide __always_inline to userspace headers")
+Signed-off-by: Matt Redfearn <matt.redfearn@mips.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Tested-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Petr Vaněk <arkamar@atlas.cz>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/swab.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/uapi/linux/swab.h b/include/uapi/linux/swab.h
+index 7272f85d6d6a..3736f2fe1541 100644
+--- a/include/uapi/linux/swab.h
++++ b/include/uapi/linux/swab.h
+@@ -3,7 +3,7 @@
+ #define _UAPI_LINUX_SWAB_H
+ #include <linux/types.h>
+-#include <linux/compiler.h>
++#include <linux/stddef.h>
+ #include <asm/bitsperlong.h>
+ #include <asm/swab.h>
+-- 
+2.35.1
+
diff --git a/queue-5.10/inet-add-read_once-sk-sk_bound_dev_if-in-inet_csk_bi.patch b/queue-5.10/inet-add-read_once-sk-sk_bound_dev_if-in-inet_csk_bi.patch
new file mode 100644 (file)
index 0000000..ab33f57
--- /dev/null
@@ -0,0 +1,45 @@
+From 1bee0ba6e266e75f9576c618fa822043fbf7e788 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 May 2022 11:55:46 -0700
+Subject: inet: add READ_ONCE(sk->sk_bound_dev_if) in inet_csk_bind_conflict()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit d2c135619cb89d1d5693df81ab408c5e8e97e898 ]
+
+inet_csk_bind_conflict() can access sk->sk_bound_dev_if for
+unlocked sockets.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/inet_connection_sock.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index 4d9713324003..e54abccdffd0 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -147,10 +147,14 @@ static int inet_csk_bind_conflict(const struct sock *sk,
+        */
+       sk_for_each_bound(sk2, &tb->owners) {
+-              if (sk != sk2 &&
+-                  (!sk->sk_bound_dev_if ||
+-                   !sk2->sk_bound_dev_if ||
+-                   sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
++              int bound_dev_if2;
++
++              if (sk == sk2)
++                      continue;
++              bound_dev_if2 = READ_ONCE(sk2->sk_bound_dev_if);
++              if ((!sk->sk_bound_dev_if ||
++                   !bound_dev_if2 ||
++                   sk->sk_bound_dev_if == bound_dev_if2)) {
+                       if (reuse && sk2->sk_reuse &&
+                           sk2->sk_state != TCP_LISTEN) {
+                               if ((!relax ||
+-- 
+2.35.1
+
diff --git a/queue-5.10/input-elants_i2c-properly-handle-the-reset-gpio-when.patch b/queue-5.10/input-elants_i2c-properly-handle-the-reset-gpio-when.patch
new file mode 100644 (file)
index 0000000..5300f7c
--- /dev/null
@@ -0,0 +1,90 @@
+From 7ddcbac236446ce33d7d56154b347a875b178c97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 21:49:19 -0800
+Subject: Input: elants_i2c - properly handle the reset GPIO when power is off
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit a85fbd6498441694475716a4d5c65f9d3e073faf ]
+
+As can be seen in elants_i2c_power_off(), we want the reset GPIO
+asserted when power is off. The reset GPIO is active low so we need
+the reset line logic low when power is off to avoid leakage.
+
+We have a problem, though, at probe time. At probe time we haven't
+powered the regulators on yet but we have:
+
+  devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_LOW);
+
+While that _looks_ right, it turns out that it's not. The
+GPIOD_OUT_LOW doesn't mean to init the GPIO to low. It means init the
+GPIO to "not asserted". Since this is an active low GPIO that inits it
+to be high.
+
+Let's fix this to properly init the GPIO. Now after both probe and
+power off the state of the GPIO is consistent (it's "asserted" or
+level low).
+
+Once we fix this, we can see that at power on time we no longer to
+assert the reset GPIO as the first thing. The reset GPIO is _always_
+asserted before powering on. Let's fix powering on to account for
+this.
+
+Fixes: afe10358e47a ("Input: elants_i2c - wire up regulator support")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20221117123805.1.I9959ac561dd6e1e8e1ce7085e4de6167b27c574f@changeid
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/touchscreen/elants_i2c.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
+index c09aefa2661d..ca9cee5851a0 100644
+--- a/drivers/input/touchscreen/elants_i2c.c
++++ b/drivers/input/touchscreen/elants_i2c.c
+@@ -1219,14 +1219,12 @@ static int elants_i2c_power_on(struct elants_data *ts)
+       if (IS_ERR_OR_NULL(ts->reset_gpio))
+               return 0;
+-      gpiod_set_value_cansleep(ts->reset_gpio, 1);
+-
+       error = regulator_enable(ts->vcc33);
+       if (error) {
+               dev_err(&ts->client->dev,
+                       "failed to enable vcc33 regulator: %d\n",
+                       error);
+-              goto release_reset_gpio;
++              return error;
+       }
+       error = regulator_enable(ts->vccio);
+@@ -1235,7 +1233,7 @@ static int elants_i2c_power_on(struct elants_data *ts)
+                       "failed to enable vccio regulator: %d\n",
+                       error);
+               regulator_disable(ts->vcc33);
+-              goto release_reset_gpio;
++              return error;
+       }
+       /*
+@@ -1244,7 +1242,6 @@ static int elants_i2c_power_on(struct elants_data *ts)
+        */
+       udelay(ELAN_POWERON_DELAY_USEC);
+-release_reset_gpio:
+       gpiod_set_value_cansleep(ts->reset_gpio, 0);
+       if (error)
+               return error;
+@@ -1352,7 +1349,7 @@ static int elants_i2c_probe(struct i2c_client *client,
+               return error;
+       }
+-      ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_LOW);
++      ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+       if (IS_ERR(ts->reset_gpio)) {
+               error = PTR_ERR(ts->reset_gpio);
+-- 
+2.35.1
+
diff --git a/queue-5.10/input-joystick-fix-kconfig-warning-for-joystick_adc.patch b/queue-5.10/input-joystick-fix-kconfig-warning-for-joystick_adc.patch
new file mode 100644 (file)
index 0000000..1e95acf
--- /dev/null
@@ -0,0 +1,42 @@
+From 9c8a537bfe10989bd045b375cda6807ffc383abf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 13:12:38 -0700
+Subject: Input: joystick - fix Kconfig warning for JOYSTICK_ADC
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 6100a19c4fcfe154dd32f8a8ef4e8c0b1f607c75 ]
+
+Fix a Kconfig warning for JOYSTICK_ADC by also selecting
+IIO_BUFFER.
+
+WARNING: unmet direct dependencies detected for IIO_BUFFER_CB
+  Depends on [n]: IIO [=y] && IIO_BUFFER [=n]
+  Selected by [y]:
+  - JOYSTICK_ADC [=y] && INPUT [=y] && INPUT_JOYSTICK [=y] && IIO [=y]
+
+Fixes: 2c2b364fddd5 ("Input: joystick - add ADC attached joystick driver.")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Link: https://lore.kernel.org/r/20221104201238.31628-1-rdunlap@infradead.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/joystick/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
+index b080f0cfb068..d8ec5193a941 100644
+--- a/drivers/input/joystick/Kconfig
++++ b/drivers/input/joystick/Kconfig
+@@ -45,6 +45,7 @@ config JOYSTICK_A3D
+ config JOYSTICK_ADC
+       tristate "Simple joystick connected over ADC"
+       depends on IIO
++      select IIO_BUFFER
+       select IIO_BUFFER_CB
+       help
+         Say Y here if you have a simple joystick connected over ADC.
+-- 
+2.35.1
+
diff --git a/queue-5.10/integrity-fix-memory-leakage-in-keyring-allocation-e.patch b/queue-5.10/integrity-fix-memory-leakage-in-keyring-allocation-e.patch
new file mode 100644 (file)
index 0000000..49922f8
--- /dev/null
@@ -0,0 +1,47 @@
+From 6d6641f861b5fe4b20f9f9aaecb0e59d4885a7b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 18:13:17 +0800
+Subject: integrity: Fix memory leakage in keyring allocation error path
+
+From: GUO Zihua <guozihua@huawei.com>
+
+[ Upstream commit 39419ef7af0916cc3620ecf1ed42d29659109bf3 ]
+
+Key restriction is allocated in integrity_init_keyring(). However, if
+keyring allocation failed, it is not freed, causing memory leaks.
+
+Fixes: 2b6aa412ff23 ("KEYS: Use structure to capture key restriction function and data")
+Signed-off-by: GUO Zihua <guozihua@huawei.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/digsig.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
+index 0f518dcfde05..de442af7b336 100644
+--- a/security/integrity/digsig.c
++++ b/security/integrity/digsig.c
+@@ -120,6 +120,7 @@ int __init integrity_init_keyring(const unsigned int id)
+ {
+       struct key_restriction *restriction;
+       key_perm_t perm;
++      int ret;
+       perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
+               | KEY_USR_READ | KEY_USR_SEARCH;
+@@ -140,7 +141,10 @@ int __init integrity_init_keyring(const unsigned int id)
+       perm |= KEY_USR_WRITE;
+ out:
+-      return __integrity_init_keyring(id, perm, restriction);
++      ret = __integrity_init_keyring(id, perm, restriction);
++      if (ret)
++              kfree(restriction);
++      return ret;
+ }
+ int __init integrity_add_key(const unsigned int id, const void *data,
+-- 
+2.35.1
+
diff --git a/queue-5.10/iommu-amd-fix-pci-device-refcount-leak-in-ppr_notifi.patch b/queue-5.10/iommu-amd-fix-pci-device-refcount-leak-in-ppr_notifi.patch
new file mode 100644 (file)
index 0000000..2457774
--- /dev/null
@@ -0,0 +1,39 @@
+From a1f5e2e194c54b6f27084f789d8518573a06cc68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 17:36:04 +0800
+Subject: iommu/amd: Fix pci device refcount leak in ppr_notifier()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 6cf0981c2233f97d56938d9d61845383d6eb227c ]
+
+As comment of pci_get_domain_bus_and_slot() says, it returns
+a pci device with refcount increment, when finish using it,
+the caller must decrement the reference count by calling
+pci_dev_put(). So call it before returning from ppr_notifier()
+to avoid refcount leak.
+
+Fixes: daae2d25a477 ("iommu/amd: Don't copy GCR3 table root pointer")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221118093604.216371-1-yangyingliang@huawei.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/iommu_v2.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/iommu/amd/iommu_v2.c b/drivers/iommu/amd/iommu_v2.c
+index fb61bdca4c2c..16776e3c6eab 100644
+--- a/drivers/iommu/amd/iommu_v2.c
++++ b/drivers/iommu/amd/iommu_v2.c
+@@ -587,6 +587,7 @@ static int ppr_notifier(struct notifier_block *nb, unsigned long e, void *data)
+       put_device_state(dev_state);
+ out:
++      pci_dev_put(pdev);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/iommu-fsl_pamu-fix-resource-leak-in-fsl_pamu_probe.patch b/queue-5.10/iommu-fsl_pamu-fix-resource-leak-in-fsl_pamu_probe.patch
new file mode 100644 (file)
index 0000000..a82dd66
--- /dev/null
@@ -0,0 +1,38 @@
+From 3ccd628a7f4328a831374e04c70726ba7e01b2fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 08:20:22 +0000
+Subject: iommu/fsl_pamu: Fix resource leak in fsl_pamu_probe()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 73f5fc5f884ad0c5f7d57f66303af64f9f002526 ]
+
+The fsl_pamu_probe() returns directly when create_csd() failed, leaving
+irq and memories unreleased.
+Fix by jumping to error if create_csd() returns error.
+
+Fixes: 695093e38c3e ("iommu/fsl: Freescale PAMU driver and iommu implementation.")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Link: https://lore.kernel.org/r/20221121082022.19091-1-yuancan@huawei.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/fsl_pamu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
+index b9a974d97831..25689bdf812e 100644
+--- a/drivers/iommu/fsl_pamu.c
++++ b/drivers/iommu/fsl_pamu.c
+@@ -1122,7 +1122,7 @@ static int fsl_pamu_probe(struct platform_device *pdev)
+               ret = create_csd(ppaact_phys, mem_size, csd_port_id);
+               if (ret) {
+                       dev_err(dev, "could not create coherence subdomain\n");
+-                      return ret;
++                      goto error;
+               }
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/iommu-sun50i-consider-all-fault-sources-for-reset.patch b/queue-5.10/iommu-sun50i-consider-all-fault-sources-for-reset.patch
new file mode 100644 (file)
index 0000000..39096b6
--- /dev/null
@@ -0,0 +1,60 @@
+From 4d978037da86d876e5e3dc152de25fc3c71e11d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Oct 2022 18:54:12 +0200
+Subject: iommu/sun50i: Consider all fault sources for reset
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit cef20703e2b2276aaa402ec5a65ec9a09963b83e ]
+
+We have to reset masters for all faults - permissions, L1 fault or L2
+fault. Currently it's done only for permissions. If other type of fault
+happens, master is in locked up state. Fix that by really considering
+all fault sources.
+
+Fixes: 4100b8c229b3 ("iommu: Add Allwinner H6 IOMMU driver")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20221025165415.307591-3-jernej.skrabec@gmail.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/sun50i-iommu.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
+index 3dead4f91420..2512eabbf4ac 100644
+--- a/drivers/iommu/sun50i-iommu.c
++++ b/drivers/iommu/sun50i-iommu.c
+@@ -881,8 +881,8 @@ static phys_addr_t sun50i_iommu_handle_perm_irq(struct sun50i_iommu *iommu)
+ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+ {
++      u32 status, l1_status, l2_status, resets;
+       struct sun50i_iommu *iommu = dev_id;
+-      u32 status;
+       spin_lock(&iommu->iommu_lock);
+@@ -892,6 +892,9 @@ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+               return IRQ_NONE;
+       }
++      l1_status = iommu_read(iommu, IOMMU_L1PG_INT_REG);
++      l2_status = iommu_read(iommu, IOMMU_L2PG_INT_REG);
++
+       if (status & IOMMU_INT_INVALID_L2PG)
+               sun50i_iommu_handle_pt_irq(iommu,
+                                           IOMMU_INT_ERR_ADDR_L2_REG,
+@@ -905,7 +908,8 @@ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+       iommu_write(iommu, IOMMU_INT_CLR_REG, status);
+-      iommu_write(iommu, IOMMU_RESET_REG, ~status);
++      resets = (status | l1_status | l2_status) & IOMMU_INT_MASTER_MASK;
++      iommu_write(iommu, IOMMU_RESET_REG, ~resets);
+       iommu_write(iommu, IOMMU_RESET_REG, IOMMU_RESET_RELEASE_ALL);
+       spin_unlock(&iommu->iommu_lock);
+-- 
+2.35.1
+
diff --git a/queue-5.10/iommu-sun50i-fix-flush-size.patch b/queue-5.10/iommu-sun50i-fix-flush-size.patch
new file mode 100644 (file)
index 0000000..dc43622
--- /dev/null
@@ -0,0 +1,37 @@
+From 2c9669414ee1decf93e26f4ceafadc1d5b49f322 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Oct 2022 18:54:14 +0200
+Subject: iommu/sun50i: Fix flush size
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit 67a8a67f9eceb72e4c73d1d09ed9ab04f4b8e12d ]
+
+Function sun50i_table_flush() takes number of entries as an argument,
+not number of bytes. Fix that mistake in sun50i_dte_get_page_table().
+
+Fixes: 4100b8c229b3 ("iommu: Add Allwinner H6 IOMMU driver")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20221025165415.307591-5-jernej.skrabec@gmail.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/sun50i-iommu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
+index 68aee56e2231..dc8ad35cbc4e 100644
+--- a/drivers/iommu/sun50i-iommu.c
++++ b/drivers/iommu/sun50i-iommu.c
+@@ -513,7 +513,7 @@ static u32 *sun50i_dte_get_page_table(struct sun50i_iommu_domain *sun50i_domain,
+               sun50i_iommu_free_page_table(iommu, drop_pt);
+       }
+-      sun50i_table_flush(sun50i_domain, page_table, PT_SIZE);
++      sun50i_table_flush(sun50i_domain, page_table, NUM_PT_ENTRIES);
+       sun50i_table_flush(sun50i_domain, dte_addr, 1);
+       return page_table;
+-- 
+2.35.1
+
diff --git a/queue-5.10/iommu-sun50i-fix-r-w-permission-check.patch b/queue-5.10/iommu-sun50i-fix-r-w-permission-check.patch
new file mode 100644 (file)
index 0000000..4e9a5c5
--- /dev/null
@@ -0,0 +1,43 @@
+From 3699d262118eab7cd9eb0e6bf5dfea7559b094c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Oct 2022 18:54:13 +0200
+Subject: iommu/sun50i: Fix R/W permission check
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit eac0104dc69be50bed86926d6f32e82b44f8c921 ]
+
+Because driver has enum type permissions and iommu subsystem has bitmap
+type, we have to be careful how check for combined read and write
+permissions is done. In such case, we have to mask both permissions and
+check that both are set at the same time.
+
+Current code just masks both flags but doesn't check that both are set.
+In short, it always sets R/W permission, regardles if requested
+permissions were RO, WO or RW. Fix that.
+
+Fixes: 4100b8c229b3 ("iommu: Add Allwinner H6 IOMMU driver")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20221025165415.307591-4-jernej.skrabec@gmail.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/sun50i-iommu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
+index 2512eabbf4ac..68aee56e2231 100644
+--- a/drivers/iommu/sun50i-iommu.c
++++ b/drivers/iommu/sun50i-iommu.c
+@@ -272,7 +272,7 @@ static u32 sun50i_mk_pte(phys_addr_t page, int prot)
+       enum sun50i_iommu_aci aci;
+       u32 flags = 0;
+-      if (prot & (IOMMU_READ | IOMMU_WRITE))
++      if ((prot & (IOMMU_READ | IOMMU_WRITE)) == (IOMMU_READ | IOMMU_WRITE))
+               aci = SUN50I_IOMMU_ACI_RD_WR;
+       else if (prot & IOMMU_READ)
+               aci = SUN50I_IOMMU_ACI_RD;
+-- 
+2.35.1
+
diff --git a/queue-5.10/iommu-sun50i-fix-reset-release.patch b/queue-5.10/iommu-sun50i-fix-reset-release.patch
new file mode 100644 (file)
index 0000000..807cf3f
--- /dev/null
@@ -0,0 +1,54 @@
+From 4971a6748282eb23244d5ee4b7c10472e88a1961 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Oct 2022 18:54:11 +0200
+Subject: iommu/sun50i: Fix reset release
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit 9ad0c1252e84dbc664f0462707182245ed603237 ]
+
+Reset signal is asserted by writing 0 to the corresponding locations of
+masters we want to reset. So in order to deassert all reset signals, we
+should write 1's to all locations.
+
+Current code writes 1's to locations of masters which were just reset
+which is good. However, at the same time it also writes 0's to other
+locations and thus asserts reset signals of remaining masters. Fix code
+by writing all 1's when we want to deassert all reset signals.
+
+This bug was discovered when working with Cedrus (video decoder). When
+it faulted, display went blank due to reset signal assertion.
+
+Fixes: 4100b8c229b3 ("iommu: Add Allwinner H6 IOMMU driver")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20221025165415.307591-2-jernej.skrabec@gmail.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/sun50i-iommu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
+index ea6db1341916..3dead4f91420 100644
+--- a/drivers/iommu/sun50i-iommu.c
++++ b/drivers/iommu/sun50i-iommu.c
+@@ -28,6 +28,7 @@
+ #include <linux/types.h>
+ #define IOMMU_RESET_REG                       0x010
++#define IOMMU_RESET_RELEASE_ALL                       0xffffffff
+ #define IOMMU_ENABLE_REG              0x020
+ #define IOMMU_ENABLE_ENABLE                   BIT(0)
+@@ -905,7 +906,7 @@ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+       iommu_write(iommu, IOMMU_INT_CLR_REG, status);
+       iommu_write(iommu, IOMMU_RESET_REG, ~status);
+-      iommu_write(iommu, IOMMU_RESET_REG, status);
++      iommu_write(iommu, IOMMU_RESET_REG, IOMMU_RESET_RELEASE_ALL);
+       spin_unlock(&iommu->iommu_lock);
+-- 
+2.35.1
+
diff --git a/queue-5.10/iommu-sun50i-remove-iommu_domain_identity.patch b/queue-5.10/iommu-sun50i-remove-iommu_domain_identity.patch
new file mode 100644 (file)
index 0000000..d617aaa
--- /dev/null
@@ -0,0 +1,44 @@
+From 8be0fbdf02f7ae4a47d0e97497177cca7e8806ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 10:06:28 -0400
+Subject: iommu/sun50i: Remove IOMMU_DOMAIN_IDENTITY
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit ef5bb8e7a7127218f826b9ccdf7508e7a339f4c2 ]
+
+This driver treats IOMMU_DOMAIN_IDENTITY the same as UNMANAGED, which
+cannot possibly be correct.
+
+UNMANAGED domains are required to start out blocking all DMAs. This seems
+to be what this driver does as it allocates a first level 'dt' for the IO
+page table that is 0 filled.
+
+Thus UNMANAGED looks like a working IO page table, and so IDENTITY must be
+a mistake. Remove it.
+
+Fixes: 4100b8c229b3 ("iommu: Add Allwinner H6 IOMMU driver")
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/0-v1-97f0adf27b5e+1f0-s50_identity_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/sun50i-iommu.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
+index dc8ad35cbc4e..65aa30d55d3a 100644
+--- a/drivers/iommu/sun50i-iommu.c
++++ b/drivers/iommu/sun50i-iommu.c
+@@ -603,7 +603,6 @@ static struct iommu_domain *sun50i_iommu_domain_alloc(unsigned type)
+       struct sun50i_iommu_domain *sun50i_domain;
+       if (type != IOMMU_DOMAIN_DMA &&
+-          type != IOMMU_DOMAIN_IDENTITY &&
+           type != IOMMU_DOMAIN_UNMANAGED)
+               return NULL;
+-- 
+2.35.1
+
diff --git a/queue-5.10/ipmi-fix-memleak-when-unload-ipmi-driver.patch b/queue-5.10/ipmi-fix-memleak-when-unload-ipmi-driver.patch
new file mode 100644 (file)
index 0000000..74a5b5e
--- /dev/null
@@ -0,0 +1,64 @@
+From ece22ad4d5e1af6ad841b53bf435a5dce4a68e2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Oct 2022 17:26:17 +0800
+Subject: ipmi: fix memleak when unload ipmi driver
+
+From: Zhang Yuchen <zhangyuchen.lcr@bytedance.com>
+
+[ Upstream commit 36992eb6b9b83f7f9cdc8e74fb5799d7b52e83e9 ]
+
+After the IPMI disconnect problem, the memory kept rising and we tried
+to unload the driver to free the memory. However, only part of the
+free memory is recovered after the driver is uninstalled. Using
+ebpf to hook free functions, we find that neither ipmi_user nor
+ipmi_smi_msg is free, only ipmi_recv_msg is free.
+
+We find that the deliver_smi_err_response call in clean_smi_msgs does
+the destroy processing on each message from the xmit_msg queue without
+checking the return value and free ipmi_smi_msg.
+
+deliver_smi_err_response is called only at this location. Adding the
+free handling has no effect.
+
+To verify, try using ebpf to trace the free function.
+
+  $ bpftrace -e 'kretprobe:ipmi_alloc_recv_msg {printf("alloc rcv
+      %p\n",retval);} kprobe:free_recv_msg {printf("free recv %p\n",
+      arg0)} kretprobe:ipmi_alloc_smi_msg {printf("alloc smi %p\n",
+        retval);} kprobe:free_smi_msg {printf("free smi  %p\n",arg0)}'
+
+Signed-off-by: Zhang Yuchen <zhangyuchen.lcr@bytedance.com>
+Message-Id: <20221007092617.87597-4-zhangyuchen.lcr@bytedance.com>
+[Fixed the comment above handle_one_recv_msg().]
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/ipmi/ipmi_msghandler.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
+index 05e7339752ac..223b90247648 100644
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -3540,12 +3540,16 @@ static void deliver_smi_err_response(struct ipmi_smi *intf,
+                                    struct ipmi_smi_msg *msg,
+                                    unsigned char err)
+ {
++      int rv;
+       msg->rsp[0] = msg->data[0] | 4;
+       msg->rsp[1] = msg->data[1];
+       msg->rsp[2] = err;
+       msg->rsp_size = 3;
+-      /* It's an error, so it will never requeue, no need to check return. */
+-      handle_one_recv_msg(intf, msg);
++
++      /* This will never requeue, but it may ask us to free the message. */
++      rv = handle_one_recv_msg(intf, msg);
++      if (rv == 0)
++              ipmi_free_smi_msg(msg);
+ }
+ static void cleanup_smi_msgs(struct ipmi_smi *intf)
+-- 
+2.35.1
+
diff --git a/queue-5.10/irqchip-gic-pm-use-pm_runtime_resume_and_get-in-gic_.patch b/queue-5.10/irqchip-gic-pm-use-pm_runtime_resume_and_get-in-gic_.patch
new file mode 100644 (file)
index 0000000..8d5581d
--- /dev/null
@@ -0,0 +1,39 @@
+From c99b41c7f53d793d72bfbb140ad2eee870fd5a09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Nov 2022 14:51:50 +0800
+Subject: irqchip: gic-pm: Use pm_runtime_resume_and_get() in gic_probe()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit f9ee20c85b3a3ba0afd3672630ec4f93d339f015 ]
+
+gic_probe() calls pm_runtime_get_sync() and added fail path as
+rpm_put to put usage_counter. However, pm_runtime_get_sync()
+will increment usage_counter even it failed. Fix it by replacing it with
+pm_runtime_resume_and_get() to keep usage counter balanced.
+
+Fixes: 9c8edddfc992 ("irqchip/gic: Add platform driver for non-root GICs that require RPM")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20221124065150.22809-1-shangxiaojing@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-gic-pm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/irq-gic-pm.c b/drivers/irqchip/irq-gic-pm.c
+index 1337ceceb59b..8be7d136c3bf 100644
+--- a/drivers/irqchip/irq-gic-pm.c
++++ b/drivers/irqchip/irq-gic-pm.c
+@@ -104,7 +104,7 @@ static int gic_probe(struct platform_device *pdev)
+       pm_runtime_enable(dev);
+-      ret = pm_runtime_get_sync(dev);
++      ret = pm_runtime_resume_and_get(dev);
+       if (ret < 0)
+               goto rpm_disable;
+-- 
+2.35.1
+
diff --git a/queue-5.10/kbuild-refactor-single-builds-of-.ko.patch b/queue-5.10/kbuild-refactor-single-builds-of-.ko.patch
new file mode 100644 (file)
index 0000000..95a3e89
--- /dev/null
@@ -0,0 +1,70 @@
+From c7ca63fe7c798135877b45b9f3b0221af1e87c9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Aug 2022 11:39:50 +0900
+Subject: kbuild: refactor single builds of *.ko
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit f110e5a250e3c5db417e094b3dd86f1c135291ca ]
+
+Remove the potentially invalid modules.order instead of using
+the temporary file.
+
+Also, KBUILD_MODULES is don't care for single builds. No need to
+cancel it.
+
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Stable-dep-of: c7b98de745cf ("phy: qcom-qmp-combo: fix runtime suspend")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Makefile | 16 ++++------------
+ 1 file changed, 4 insertions(+), 12 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index e32d3137b1d9..36aff1531386 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1766,6 +1766,8 @@ modules modules_install:
+       @echo >&2 '***'
+       @exit 1
++KBUILD_MODULES :=
++
+ endif # CONFIG_MODULES
+ # Single targets
+@@ -1791,18 +1793,12 @@ $(single-ko): single_modpost
+ $(single-no-ko): descend
+       @:
+-ifeq ($(KBUILD_EXTMOD),)
+-# For the single build of in-tree modules, use a temporary file to avoid
+-# the situation of modules_install installing an invalid modules.order.
+-MODORDER := .modules.tmp
+-endif
+-
++# Remove MODORDER when done because it is not the real one.
+ PHONY += single_modpost
+ single_modpost: $(single-no-ko) modules_prepare
+       $(Q){ $(foreach m, $(single-ko), echo $(extmod-prefix)$m;) } > $(MODORDER)
+       $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
+-
+-KBUILD_MODULES := 1
++      $(Q)rm -f $(MODORDER)
+ export KBUILD_SINGLE_TARGETS := $(addprefix $(extmod-prefix), $(single-no-ko))
+@@ -1812,10 +1808,6 @@ build-dirs := $(foreach d, $(build-dirs), \
+ endif
+-ifndef CONFIG_MODULES
+-KBUILD_MODULES :=
+-endif
+-
+ # Handle descending into subdirectories listed in $(build-dirs)
+ # Preset locale variables to speed up the build process. Limit locale
+ # tweaks to this spot to avoid wrong language settings when running
+-- 
+2.35.1
+
diff --git a/queue-5.10/kbuild-remove-unneeded-mkdir-for-external-modules_in.patch b/queue-5.10/kbuild-remove-unneeded-mkdir-for-external-modules_in.patch
new file mode 100644 (file)
index 0000000..354d416
--- /dev/null
@@ -0,0 +1,36 @@
+From a824004d1b531253f0d7db2f8ff59d5be6cd9a65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 22:38:02 +0900
+Subject: kbuild: remove unneeded mkdir for external modules_install
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 4b97ec0e9cfd5995f41b9726c88566a31f4625cc ]
+
+scripts/Makefile.modinst creates directories as needed.
+
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Stable-dep-of: c7b98de745cf ("phy: qcom-qmp-combo: fix runtime suspend")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Makefile | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 68f8efa0cc30..9be2a818d4d7 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1746,10 +1746,8 @@ $(MODORDER): descend
+ PHONY += modules_install
+ modules_install: _emodinst_ _emodinst_post
+-install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra)
+ PHONY += _emodinst_
+ _emodinst_:
+-      $(Q)mkdir -p $(MODLIB)/$(install-dir)
+       $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
+ PHONY += _emodinst_post
+-- 
+2.35.1
+
diff --git a/queue-5.10/kbuild-unify-modules-_install-for-in-tree-and-extern.patch b/queue-5.10/kbuild-unify-modules-_install-for-in-tree-and-extern.patch
new file mode 100644 (file)
index 0000000..9d7017b
--- /dev/null
@@ -0,0 +1,168 @@
+From b9e567d31414b5096ce2c57e0c0be306170c0652 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 22:38:03 +0900
+Subject: kbuild: unify modules(_install) for in-tree and external modules
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 3e3005df73b535cb849cf4ec8075d6aa3c460f68 ]
+
+If you attempt to build or install modules ('make modules(_install)'
+with CONFIG_MODULES disabled, you will get a clear error message, but
+nothing for external module builds.
+
+Factor out the modules and modules_install rules into the common part,
+so you will get the same error message when you try to build external
+modules with CONFIG_MODULES=n.
+
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Stable-dep-of: c7b98de745cf ("phy: qcom-qmp-combo: fix runtime suspend")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Makefile | 85 ++++++++++++++++++++++++--------------------------------
+ 1 file changed, 36 insertions(+), 49 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 9be2a818d4d7..e32d3137b1d9 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1425,7 +1425,6 @@ endif
+ PHONY += modules
+ modules: $(if $(KBUILD_BUILTIN),vmlinux) modules_check modules_prepare
+-      $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
+ PHONY += modules_check
+ modules_check: modules.order
+@@ -1443,12 +1442,9 @@ PHONY += modules_prepare
+ modules_prepare: prepare
+       $(Q)$(MAKE) $(build)=scripts scripts/module.lds
+-# Target to install modules
+-PHONY += modules_install
+-modules_install: _modinst_ _modinst_post
+-
+-PHONY += _modinst_
+-_modinst_:
++modules_install: __modinst_pre
++PHONY += __modinst_pre
++__modinst_pre:
+       @rm -rf $(MODLIB)/kernel
+       @rm -f $(MODLIB)/source
+       @mkdir -p $(MODLIB)/kernel
+@@ -1460,14 +1456,6 @@ _modinst_:
+       @sed 's:^:kernel/:' modules.order > $(MODLIB)/modules.order
+       @cp -f modules.builtin $(MODLIB)/
+       @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
+-      $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
+-
+-# This depmod is only for convenience to give the initial
+-# boot a modules.dep even before / is mounted read-write.  However the
+-# boot script depmod is the master version.
+-PHONY += _modinst_post
+-_modinst_post: _modinst_
+-      $(call cmd,depmod)
+ ifeq ($(CONFIG_MODULE_SIG), y)
+ PHONY += modules_sign
+@@ -1475,20 +1463,6 @@ modules_sign:
+       $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modsign
+ endif
+-else # CONFIG_MODULES
+-
+-# Modules not configured
+-# ---------------------------------------------------------------------------
+-
+-PHONY += modules modules_install
+-modules modules_install:
+-      @echo >&2
+-      @echo >&2 "The present kernel configuration has modules disabled."
+-      @echo >&2 "Type 'make config' and enable loadable module support."
+-      @echo >&2 "Then build a kernel with module support enabled."
+-      @echo >&2
+-      @exit 1
+-
+ endif # CONFIG_MODULES
+ ###
+@@ -1736,24 +1710,9 @@ KBUILD_BUILTIN :=
+ KBUILD_MODULES := 1
+ build-dirs := $(KBUILD_EXTMOD)
+-PHONY += modules
+-modules: $(MODORDER)
+-      $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
+-
+ $(MODORDER): descend
+       @:
+-PHONY += modules_install
+-modules_install: _emodinst_ _emodinst_post
+-
+-PHONY += _emodinst_
+-_emodinst_:
+-      $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
+-
+-PHONY += _emodinst_post
+-_emodinst_post: _emodinst_
+-      $(call cmd,depmod)
+-
+ compile_commands.json: $(extmod-prefix)compile_commands.json
+ PHONY += compile_commands.json
+@@ -1776,6 +1735,39 @@ PHONY += prepare modules_prepare
+ endif # KBUILD_EXTMOD
++# ---------------------------------------------------------------------------
++# Modules
++
++PHONY += modules modules_install
++
++ifdef CONFIG_MODULES
++
++modules: $(MODORDER)
++      $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
++
++quiet_cmd_depmod = DEPMOD  $(KERNELRELEASE)
++      cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \
++                   $(KERNELRELEASE)
++
++modules_install:
++      $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
++      $(call cmd,depmod)
++
++else # CONFIG_MODULES
++
++# Modules not configured
++# ---------------------------------------------------------------------------
++
++modules modules_install:
++      @echo >&2 '***'
++      @echo >&2 '*** The present kernel configuration has modules disabled.'
++      @echo >&2 '*** To use the module feature, please run "make menuconfig" etc.'
++      @echo >&2 '*** to enable CONFIG_MODULES.'
++      @echo >&2 '***'
++      @exit 1
++
++endif # CONFIG_MODULES
++
+ # Single targets
+ # ---------------------------------------------------------------------------
+ # To build individual files in subdirectories, you can do like this:
+@@ -1963,11 +1955,6 @@ tools/%: FORCE
+ quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN   $(wildcard $(rm-files)))
+       cmd_rmfiles = rm -rf $(rm-files)
+-# Run depmod only if we have System.map and depmod is executable
+-quiet_cmd_depmod = DEPMOD  $(KERNELRELEASE)
+-      cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \
+-                   $(KERNELRELEASE)
+-
+ # read saved command lines for existing targets
+ existing-targets := $(wildcard $(sort $(targets)))
+-- 
+2.35.1
+
diff --git a/queue-5.10/lib-debugobjects-fix-stat-count-and-optimize-debug_o.patch b/queue-5.10/lib-debugobjects-fix-stat-count-and-optimize-debug_o.patch
new file mode 100644 (file)
index 0000000..c246d6c
--- /dev/null
@@ -0,0 +1,76 @@
+From b31ecdf138ed37f817edacce8cf3cb1f031b35bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jun 2022 21:06:34 +0800
+Subject: lib/debugobjects: fix stat count and optimize debug_objects_mem_init
+
+From: wuchi <wuchi.zero@gmail.com>
+
+[ Upstream commit eabb7f1ace53e127309407b2b5e74e8199e85270 ]
+
+1. Var debug_objects_allocated tracks valid kmem_cache_alloc calls, so
+   track it in debug_objects_replace_static_objects.  Do similar things in
+   object_cpu_offline.
+
+2. In debug_objects_mem_init, there is no need to call function
+   cpuhp_setup_state_nocalls when debug_objects_enabled = 0 (out of
+   memory).
+
+Link: https://lkml.kernel.org/r/20220611130634.99741-1-wuchi.zero@gmail.com
+Fixes: 634d61f45d6f ("debugobjects: Percpu pool lookahead freeing/allocation")
+Fixes: c4b73aabd098 ("debugobjects: Track number of kmem_cache_alloc/kmem_cache_free done")
+Signed-off-by: wuchi <wuchi.zero@gmail.com>
+Reviewed-by: Waiman Long <longman@redhat.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Kees Cook <keescook@chromium.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/debugobjects.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/lib/debugobjects.c b/lib/debugobjects.c
+index 9e14ae02306b..71bdc167a9ee 100644
+--- a/lib/debugobjects.c
++++ b/lib/debugobjects.c
+@@ -440,6 +440,7 @@ static int object_cpu_offline(unsigned int cpu)
+       struct debug_percpu_free *percpu_pool;
+       struct hlist_node *tmp;
+       struct debug_obj *obj;
++      unsigned long flags;
+       /* Remote access is safe as the CPU is dead already */
+       percpu_pool = per_cpu_ptr(&percpu_obj_pool, cpu);
+@@ -447,6 +448,12 @@ static int object_cpu_offline(unsigned int cpu)
+               hlist_del(&obj->node);
+               kmem_cache_free(obj_cache, obj);
+       }
++
++      raw_spin_lock_irqsave(&pool_lock, flags);
++      obj_pool_used -= percpu_pool->obj_free;
++      debug_objects_freed += percpu_pool->obj_free;
++      raw_spin_unlock_irqrestore(&pool_lock, flags);
++
+       percpu_pool->obj_free = 0;
+       return 0;
+@@ -1316,6 +1323,8 @@ static int __init debug_objects_replace_static_objects(void)
+               hlist_add_head(&obj->node, &objects);
+       }
++      debug_objects_allocated += i;
++
+       /*
+        * debug_objects_mem_init() is now called early that only one CPU is up
+        * and interrupts have been disabled, so it is safe to replace the
+@@ -1384,6 +1393,7 @@ void __init debug_objects_mem_init(void)
+               debug_objects_enabled = 0;
+               kmem_cache_destroy(obj_cache);
+               pr_warn("out of memory.\n");
++              return;
+       } else
+               debug_objects_selftest();
+-- 
+2.35.1
+
diff --git a/queue-5.10/lib-fonts-fix-undefined-behavior-in-bit-shift-for-ge.patch b/queue-5.10/lib-fonts-fix-undefined-behavior-in-bit-shift-for-ge.patch
new file mode 100644 (file)
index 0000000..46902aa
--- /dev/null
@@ -0,0 +1,79 @@
+From f513b4a620262869ef9c78c1c6e3ac5e2c96cc34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Oct 2022 19:38:29 +0800
+Subject: lib/fonts: fix undefined behavior in bit shift for get_default_font
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 6fe888c4d2fb174408e4540bb2d5602b9f507f90 ]
+
+Shifting signed 32-bit value by 31 bits is undefined, so changing
+significant bit to unsigned.  The UBSAN warning calltrace like below:
+
+UBSAN: shift-out-of-bounds in lib/fonts/fonts.c:139:20
+left shift of 1 by 31 places cannot be represented in type 'int'
+ <TASK>
+ dump_stack_lvl+0x7d/0xa5
+ dump_stack+0x15/0x1b
+ ubsan_epilogue+0xe/0x4e
+ __ubsan_handle_shift_out_of_bounds+0x1e7/0x20c
+ get_default_font+0x1c7/0x1f0
+ fbcon_startup+0x347/0x3a0
+ do_take_over_console+0xce/0x270
+ do_fbcon_takeover+0xa1/0x170
+ do_fb_registered+0x2a8/0x340
+ fbcon_fb_registered+0x47/0xe0
+ register_framebuffer+0x294/0x4a0
+ __drm_fb_helper_initial_config_and_unlock+0x43c/0x880 [drm_kms_helper]
+ drm_fb_helper_initial_config+0x52/0x80 [drm_kms_helper]
+ drm_fbdev_client_hotplug+0x156/0x1b0 [drm_kms_helper]
+ drm_fbdev_generic_setup+0xfc/0x290 [drm_kms_helper]
+ bochs_pci_probe+0x6ca/0x772 [bochs]
+ local_pci_probe+0x4d/0xb0
+ pci_device_probe+0x119/0x320
+ really_probe+0x181/0x550
+ __driver_probe_device+0xc6/0x220
+ driver_probe_device+0x32/0x100
+ __driver_attach+0x195/0x200
+ bus_for_each_dev+0xbb/0x120
+ driver_attach+0x27/0x30
+ bus_add_driver+0x22e/0x2f0
+ driver_register+0xa9/0x190
+ __pci_register_driver+0x90/0xa0
+ bochs_pci_driver_init+0x52/0x1000 [bochs]
+ do_one_initcall+0x76/0x430
+ do_init_module+0x61/0x28a
+ load_module+0x1f82/0x2e50
+ __do_sys_finit_module+0xf8/0x190
+ __x64_sys_finit_module+0x23/0x30
+ do_syscall_64+0x58/0x80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+ </TASK>
+
+Link: https://lkml.kernel.org/r/20221031113829.4183153-1-cuigaosheng1@huawei.com
+Fixes: c81f717cb9e0 ("fbcon: Fix typo and bogus logic in get_default_font")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/fonts/fonts.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/fonts/fonts.c b/lib/fonts/fonts.c
+index 5f4b07b56cd9..973866438608 100644
+--- a/lib/fonts/fonts.c
++++ b/lib/fonts/fonts.c
+@@ -135,8 +135,8 @@ const struct font_desc *get_default_font(int xres, int yres, u32 font_w,
+               if (res > 20)
+                       c += 20 - res;
+-              if ((font_w & (1 << (f->width - 1))) &&
+-                  (font_h & (1 << (f->height - 1))))
++              if ((font_w & (1U << (f->width - 1))) &&
++                  (font_h & (1U << (f->height - 1))))
+                       c += 1000;
+               if (c > cc) {
+-- 
+2.35.1
+
diff --git a/queue-5.10/lib-notifier-error-inject-fix-error-when-writing-err.patch b/queue-5.10/lib-notifier-error-inject-fix-error-when-writing-err.patch
new file mode 100644 (file)
index 0000000..0728d4c
--- /dev/null
@@ -0,0 +1,52 @@
+From 81b6c81636289a50054bd1f1347515e2263332ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Sep 2022 02:24:17 +0900
+Subject: lib/notifier-error-inject: fix error when writing -errno to debugfs
+ file
+
+From: Akinobu Mita <akinobu.mita@gmail.com>
+
+[ Upstream commit f883c3edd2c432a2931ec8773c70a570115a50fe ]
+
+The simple attribute files do not accept a negative value since the commit
+488dac0c9237 ("libfs: fix error cast of negative value in
+simple_attr_write()").
+
+This restores the previous behaviour by using newly introduced
+DEFINE_SIMPLE_ATTRIBUTE_SIGNED instead of DEFINE_SIMPLE_ATTRIBUTE.
+
+Link: https://lkml.kernel.org/r/20220919172418.45257-3-akinobu.mita@gmail.com
+Fixes: 488dac0c9237 ("libfs: fix error cast of negative value in simple_attr_write()")
+Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
+Reported-by: Zhao Gongyi <zhaogongyi@huawei.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Rafael J. Wysocki <rafael@kernel.org>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Wei Yongjun <weiyongjun1@huawei.com>
+Cc: Yicong Yang <yangyicong@hisilicon.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/notifier-error-inject.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/notifier-error-inject.c b/lib/notifier-error-inject.c
+index 21016b32d313..2b24ea6c9497 100644
+--- a/lib/notifier-error-inject.c
++++ b/lib/notifier-error-inject.c
+@@ -15,7 +15,7 @@ static int debugfs_errno_get(void *data, u64 *val)
+       return 0;
+ }
+-DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set,
++DEFINE_SIMPLE_ATTRIBUTE_SIGNED(fops_errno, debugfs_errno_get, debugfs_errno_set,
+                       "%lld\n");
+ static struct dentry *debugfs_create_errno(const char *name, umode_t mode,
+-- 
+2.35.1
+
diff --git a/queue-5.10/libbpf-avoid-enum-forward-declarations-in-public-api.patch b/queue-5.10/libbpf-avoid-enum-forward-declarations-in-public-api.patch
new file mode 100644 (file)
index 0000000..7a75376
--- /dev/null
@@ -0,0 +1,71 @@
+From 66b8535fb5f4c91eedf8879f6011c54a97626f49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Nov 2022 12:00:12 -0800
+Subject: libbpf: Avoid enum forward-declarations in public API in C++ mode
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit b42693415b86f608049cf1b4870adc1dc65e58b0 ]
+
+C++ enum forward declarations are fundamentally not compatible with pure
+C enum definitions, and so libbpf's use of `enum bpf_stats_type;`
+forward declaration in libbpf/bpf.h public API header is causing C++
+compilation issues.
+
+More details can be found in [0], but it comes down to C++ supporting
+enum forward declaration only with explicitly specified backing type:
+
+  enum bpf_stats_type: int;
+
+In C (and I believe it's a GCC extension also), such forward declaration
+is simply:
+
+  enum bpf_stats_type;
+
+Further, in Linux UAPI this enum is defined in pure C way:
+
+enum bpf_stats_type { BPF_STATS_RUN_TIME = 0; }
+
+And even though in both cases backing type is int, which can be
+confirmed by looking at DWARF information, for C++ compiler actual enum
+definition and forward declaration are incompatible.
+
+To eliminate this problem, for C++ mode define input argument as int,
+which makes enum unnecessary in libbpf public header. This solves the
+issue and as demonstrated by next patch doesn't cause any unwanted
+compiler warnings, at least with default warnings setting.
+
+  [0] https://stackoverflow.com/questions/42766839/c11-enum-forward-causes-underlying-type-mismatch
+  [1] Closes: https://github.com/libbpf/libbpf/issues/249
+
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20221130200013.2997831-1-andrii@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/bpf.h | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
+index 875dde20d56e..92a3eaa154dd 100644
+--- a/tools/lib/bpf/bpf.h
++++ b/tools/lib/bpf/bpf.h
+@@ -241,8 +241,15 @@ LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
+                                __u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
+                                __u64 *probe_offset, __u64 *probe_addr);
++#ifdef __cplusplus
++/* forward-declaring enums in C++ isn't compatible with pure C enums, so
++ * instead define bpf_enable_stats() as accepting int as an input
++ */
++LIBBPF_API int bpf_enable_stats(int type);
++#else
+ enum bpf_stats_type; /* defined in up-to-date linux/bpf.h */
+ LIBBPF_API int bpf_enable_stats(enum bpf_stats_type type);
++#endif
+ struct bpf_prog_bind_opts {
+       size_t sz; /* size of this struct for forward/backward compatibility */
+-- 
+2.35.1
+
diff --git a/queue-5.10/libbpf-fix-null-pointer-dereference-in-find_prog_by_.patch b/queue-5.10/libbpf-fix-null-pointer-dereference-in-find_prog_by_.patch
new file mode 100644 (file)
index 0000000..e1b4f5c
--- /dev/null
@@ -0,0 +1,43 @@
+From 3908cc082bb8ebd156900f60e90b27b1e7aae96f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Oct 2022 10:23:53 +0800
+Subject: libbpf: Fix null-pointer dereference in find_prog_by_sec_insn()
+
+From: Shung-Hsi Yu <shung-hsi.yu@suse.com>
+
+[ Upstream commit d0d382f95a9270dcf803539d6781d6bd67e3f5b2 ]
+
+When there are no program sections, obj->programs is left unallocated,
+and find_prog_by_sec_insn()'s search lands on &obj->programs[0] == NULL,
+and will cause null-pointer dereference in the following access to
+prog->sec_idx.
+
+Guard the search with obj->nr_programs similar to what's being done in
+__bpf_program__iter() to prevent null-pointer access from happening.
+
+Fixes: db2b8b06423c ("libbpf: Support CO-RE relocations for multi-prog sections")
+Signed-off-by: Shung-Hsi Yu <shung-hsi.yu@suse.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20221012022353.7350-4-shung-hsi.yu@suse.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 66d7f8d494de..015ed8253f73 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -3479,6 +3479,9 @@ static struct bpf_program *find_prog_by_sec_insn(const struct bpf_object *obj,
+       int l = 0, r = obj->nr_programs - 1, m;
+       struct bpf_program *prog;
++      if (!obj->nr_programs)
++              return NULL;
++
+       while (l < r) {
+               m = l + (r - l + 1) / 2;
+               prog = &obj->programs[m];
+-- 
+2.35.1
+
diff --git a/queue-5.10/libbpf-fix-use-after-free-in-btf_dump_name_dups.patch b/queue-5.10/libbpf-fix-use-after-free-in-btf_dump_name_dups.patch
new file mode 100644 (file)
index 0000000..3178af9
--- /dev/null
@@ -0,0 +1,141 @@
+From 0dd98c9d384afc8a8003fabc7e4dbde05d3cd8f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Oct 2022 08:01:03 -0400
+Subject: libbpf: Fix use-after-free in btf_dump_name_dups
+
+From: Xu Kuohai <xukuohai@huawei.com>
+
+[ Upstream commit 93c660ca40b5d2f7c1b1626e955a8e9fa30e0749 ]
+
+ASAN reports an use-after-free in btf_dump_name_dups:
+
+ERROR: AddressSanitizer: heap-use-after-free on address 0xffff927006db at pc 0xaaaab5dfb618 bp 0xffffdd89b890 sp 0xffffdd89b928
+READ of size 2 at 0xffff927006db thread T0
+    #0 0xaaaab5dfb614 in __interceptor_strcmp.part.0 (test_progs+0x21b614)
+    #1 0xaaaab635f144 in str_equal_fn tools/lib/bpf/btf_dump.c:127
+    #2 0xaaaab635e3e0 in hashmap_find_entry tools/lib/bpf/hashmap.c:143
+    #3 0xaaaab635e72c in hashmap__find tools/lib/bpf/hashmap.c:212
+    #4 0xaaaab6362258 in btf_dump_name_dups tools/lib/bpf/btf_dump.c:1525
+    #5 0xaaaab636240c in btf_dump_resolve_name tools/lib/bpf/btf_dump.c:1552
+    #6 0xaaaab6362598 in btf_dump_type_name tools/lib/bpf/btf_dump.c:1567
+    #7 0xaaaab6360b48 in btf_dump_emit_struct_def tools/lib/bpf/btf_dump.c:912
+    #8 0xaaaab6360630 in btf_dump_emit_type tools/lib/bpf/btf_dump.c:798
+    #9 0xaaaab635f720 in btf_dump__dump_type tools/lib/bpf/btf_dump.c:282
+    #10 0xaaaab608523c in test_btf_dump_incremental tools/testing/selftests/bpf/prog_tests/btf_dump.c:236
+    #11 0xaaaab6097530 in test_btf_dump tools/testing/selftests/bpf/prog_tests/btf_dump.c:875
+    #12 0xaaaab6314ed0 in run_one_test tools/testing/selftests/bpf/test_progs.c:1062
+    #13 0xaaaab631a0a8 in main tools/testing/selftests/bpf/test_progs.c:1697
+    #14 0xffff9676d214 in __libc_start_main ../csu/libc-start.c:308
+    #15 0xaaaab5d65990  (test_progs+0x185990)
+
+0xffff927006db is located 11 bytes inside of 16-byte region [0xffff927006d0,0xffff927006e0)
+freed by thread T0 here:
+    #0 0xaaaab5e2c7c4 in realloc (test_progs+0x24c7c4)
+    #1 0xaaaab634f4a0 in libbpf_reallocarray tools/lib/bpf/libbpf_internal.h:191
+    #2 0xaaaab634f840 in libbpf_add_mem tools/lib/bpf/btf.c:163
+    #3 0xaaaab636643c in strset_add_str_mem tools/lib/bpf/strset.c:106
+    #4 0xaaaab6366560 in strset__add_str tools/lib/bpf/strset.c:157
+    #5 0xaaaab6352d70 in btf__add_str tools/lib/bpf/btf.c:1519
+    #6 0xaaaab6353e10 in btf__add_field tools/lib/bpf/btf.c:2032
+    #7 0xaaaab6084fcc in test_btf_dump_incremental tools/testing/selftests/bpf/prog_tests/btf_dump.c:232
+    #8 0xaaaab6097530 in test_btf_dump tools/testing/selftests/bpf/prog_tests/btf_dump.c:875
+    #9 0xaaaab6314ed0 in run_one_test tools/testing/selftests/bpf/test_progs.c:1062
+    #10 0xaaaab631a0a8 in main tools/testing/selftests/bpf/test_progs.c:1697
+    #11 0xffff9676d214 in __libc_start_main ../csu/libc-start.c:308
+    #12 0xaaaab5d65990  (test_progs+0x185990)
+
+previously allocated by thread T0 here:
+    #0 0xaaaab5e2c7c4 in realloc (test_progs+0x24c7c4)
+    #1 0xaaaab634f4a0 in libbpf_reallocarray tools/lib/bpf/libbpf_internal.h:191
+    #2 0xaaaab634f840 in libbpf_add_mem tools/lib/bpf/btf.c:163
+    #3 0xaaaab636643c in strset_add_str_mem tools/lib/bpf/strset.c:106
+    #4 0xaaaab6366560 in strset__add_str tools/lib/bpf/strset.c:157
+    #5 0xaaaab6352d70 in btf__add_str tools/lib/bpf/btf.c:1519
+    #6 0xaaaab6353ff0 in btf_add_enum_common tools/lib/bpf/btf.c:2070
+    #7 0xaaaab6354080 in btf__add_enum tools/lib/bpf/btf.c:2102
+    #8 0xaaaab6082f50 in test_btf_dump_incremental tools/testing/selftests/bpf/prog_tests/btf_dump.c:162
+    #9 0xaaaab6097530 in test_btf_dump tools/testing/selftests/bpf/prog_tests/btf_dump.c:875
+    #10 0xaaaab6314ed0 in run_one_test tools/testing/selftests/bpf/test_progs.c:1062
+    #11 0xaaaab631a0a8 in main tools/testing/selftests/bpf/test_progs.c:1697
+    #12 0xffff9676d214 in __libc_start_main ../csu/libc-start.c:308
+    #13 0xaaaab5d65990  (test_progs+0x185990)
+
+The reason is that the key stored in hash table name_map is a string
+address, and the string memory is allocated by realloc() function, when
+the memory is resized by realloc() later, the old memory may be freed,
+so the address stored in name_map references to a freed memory, causing
+use-after-free.
+
+Fix it by storing duplicated string address in name_map.
+
+Fixes: 919d2b1dbb07 ("libbpf: Allow modification of BTF and add btf__add_str API")
+Signed-off-by: Xu Kuohai <xukuohai@huawei.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Martin KaFai Lau <martin.lau@kernel.org>
+Link: https://lore.kernel.org/bpf/20221011120108.782373-2-xukuohai@huaweicloud.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/btf_dump.c | 29 ++++++++++++++++++++++++++---
+ 1 file changed, 26 insertions(+), 3 deletions(-)
+
+diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
+index bd22853be4a6..0e2d63da24e9 100644
+--- a/tools/lib/bpf/btf_dump.c
++++ b/tools/lib/bpf/btf_dump.c
+@@ -188,6 +188,17 @@ static int btf_dump_resize(struct btf_dump *d)
+       return 0;
+ }
++static void btf_dump_free_names(struct hashmap *map)
++{
++      size_t bkt;
++      struct hashmap_entry *cur;
++
++      hashmap__for_each_entry(map, cur, bkt)
++              free((void *)cur->key);
++
++      hashmap__free(map);
++}
++
+ void btf_dump__free(struct btf_dump *d)
+ {
+       int i;
+@@ -206,8 +217,8 @@ void btf_dump__free(struct btf_dump *d)
+       free(d->cached_names);
+       free(d->emit_queue);
+       free(d->decl_stack);
+-      hashmap__free(d->type_names);
+-      hashmap__free(d->ident_names);
++      btf_dump_free_names(d->type_names);
++      btf_dump_free_names(d->ident_names);
+       free(d);
+ }
+@@ -1392,11 +1403,23 @@ static void btf_dump_emit_type_chain(struct btf_dump *d,
+ static size_t btf_dump_name_dups(struct btf_dump *d, struct hashmap *name_map,
+                                const char *orig_name)
+ {
++      char *old_name, *new_name;
+       size_t dup_cnt = 0;
++      int err;
++
++      new_name = strdup(orig_name);
++      if (!new_name)
++              return 1;
+       hashmap__find(name_map, orig_name, (void **)&dup_cnt);
+       dup_cnt++;
+-      hashmap__set(name_map, orig_name, (void *)dup_cnt, NULL, NULL);
++
++      err = hashmap__set(name_map, new_name, (void *)dup_cnt,
++                         (const void **)&old_name, NULL);
++      if (err)
++              free(new_name);
++
++      free(old_name);
+       return dup_cnt;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/libfs-add-define_simple_attribute_signed-for-signed-.patch b/queue-5.10/libfs-add-define_simple_attribute_signed-for-signed-.patch
new file mode 100644 (file)
index 0000000..b8e58bc
--- /dev/null
@@ -0,0 +1,139 @@
+From 4ecbfffdfd9d3f3b61c51902cfbaeddfef10299d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Sep 2022 02:24:16 +0900
+Subject: libfs: add DEFINE_SIMPLE_ATTRIBUTE_SIGNED for signed value
+
+From: Akinobu Mita <akinobu.mita@gmail.com>
+
+[ Upstream commit 2e41f274f9aa71cdcc69dc1f26a3f9304a651804 ]
+
+Patch series "fix error when writing negative value to simple attribute
+files".
+
+The simple attribute files do not accept a negative value since the commit
+488dac0c9237 ("libfs: fix error cast of negative value in
+simple_attr_write()"), but some attribute files want to accept a negative
+value.
+
+This patch (of 3):
+
+The simple attribute files do not accept a negative value since the commit
+488dac0c9237 ("libfs: fix error cast of negative value in
+simple_attr_write()"), so we have to use a 64-bit value to write a
+negative value.
+
+This adds DEFINE_SIMPLE_ATTRIBUTE_SIGNED for a signed value.
+
+Link: https://lkml.kernel.org/r/20220919172418.45257-1-akinobu.mita@gmail.com
+Link: https://lkml.kernel.org/r/20220919172418.45257-2-akinobu.mita@gmail.com
+Fixes: 488dac0c9237 ("libfs: fix error cast of negative value in simple_attr_write()")
+Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
+Reported-by: Zhao Gongyi <zhaogongyi@huawei.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Rafael J. Wysocki <rafael@kernel.org>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Wei Yongjun <weiyongjun1@huawei.com>
+Cc: Yicong Yang <yangyicong@hisilicon.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/libfs.c         | 22 +++++++++++++++++++---
+ include/linux/fs.h | 12 ++++++++++--
+ 2 files changed, 29 insertions(+), 5 deletions(-)
+
+diff --git a/fs/libfs.c b/fs/libfs.c
+index 7124c2e8df2f..aa0fbd720409 100644
+--- a/fs/libfs.c
++++ b/fs/libfs.c
+@@ -955,8 +955,8 @@ ssize_t simple_attr_read(struct file *file, char __user *buf,
+ EXPORT_SYMBOL_GPL(simple_attr_read);
+ /* interpret the buffer as a number to call the set function with */
+-ssize_t simple_attr_write(struct file *file, const char __user *buf,
+-                        size_t len, loff_t *ppos)
++static ssize_t simple_attr_write_xsigned(struct file *file, const char __user *buf,
++                        size_t len, loff_t *ppos, bool is_signed)
+ {
+       struct simple_attr *attr;
+       unsigned long long val;
+@@ -977,7 +977,10 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
+               goto out;
+       attr->set_buf[size] = '\0';
+-      ret = kstrtoull(attr->set_buf, 0, &val);
++      if (is_signed)
++              ret = kstrtoll(attr->set_buf, 0, &val);
++      else
++              ret = kstrtoull(attr->set_buf, 0, &val);
+       if (ret)
+               goto out;
+       ret = attr->set(attr->data, val);
+@@ -987,8 +990,21 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
+       mutex_unlock(&attr->mutex);
+       return ret;
+ }
++
++ssize_t simple_attr_write(struct file *file, const char __user *buf,
++                        size_t len, loff_t *ppos)
++{
++      return simple_attr_write_xsigned(file, buf, len, ppos, false);
++}
+ EXPORT_SYMBOL_GPL(simple_attr_write);
++ssize_t simple_attr_write_signed(struct file *file, const char __user *buf,
++                        size_t len, loff_t *ppos)
++{
++      return simple_attr_write_xsigned(file, buf, len, ppos, true);
++}
++EXPORT_SYMBOL_GPL(simple_attr_write_signed);
++
+ /**
+  * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
+  * @sb:               filesystem to do the file handle conversion on
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index ebfc0b2b4969..9a477e537361 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -3345,7 +3345,7 @@ void simple_transaction_set(struct file *file, size_t n);
+  * All attributes contain a text representation of a numeric value
+  * that are accessed with the get() and set() functions.
+  */
+-#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)          \
++#define DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, __is_signed)     \
+ static int __fops ## _open(struct inode *inode, struct file *file)    \
+ {                                                                     \
+       __simple_attr_check_format(__fmt, 0ull);                        \
+@@ -3356,10 +3356,16 @@ static const struct file_operations __fops = {                         \
+       .open    = __fops ## _open,                                     \
+       .release = simple_attr_release,                                 \
+       .read    = simple_attr_read,                                    \
+-      .write   = simple_attr_write,                                   \
++      .write   = (__is_signed) ? simple_attr_write_signed : simple_attr_write,        \
+       .llseek  = generic_file_llseek,                                 \
+ }
++#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)          \
++      DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, false)
++
++#define DEFINE_SIMPLE_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt)   \
++      DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, true)
++
+ static inline __printf(1, 2)
+ void __simple_attr_check_format(const char *fmt, ...)
+ {
+@@ -3374,6 +3380,8 @@ ssize_t simple_attr_read(struct file *file, char __user *buf,
+                        size_t len, loff_t *ppos);
+ ssize_t simple_attr_write(struct file *file, const char __user *buf,
+                         size_t len, loff_t *ppos);
++ssize_t simple_attr_write_signed(struct file *file, const char __user *buf,
++                               size_t len, loff_t *ppos);
+ struct ctl_table;
+ int proc_nr_files(struct ctl_table *table, int write,
+-- 
+2.35.1
+
diff --git a/queue-5.10/macintosh-fix-possible-memory-leak-in-macio_add_one_.patch b/queue-5.10/macintosh-fix-possible-memory-leak-in-macio_add_one_.patch
new file mode 100644 (file)
index 0000000..ab2adcb
--- /dev/null
@@ -0,0 +1,43 @@
+From c8894b4f7d98c06ce8d90a301cafe1199108f890 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 11:25:51 +0800
+Subject: macintosh: fix possible memory leak in macio_add_one_device()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 5ca86eae55a2f006e6c1edd2029b2cacb6979515 ]
+
+Afer commit 1fa5ae857bb1 ("driver core: get rid of struct device's
+bus_id string array"), the name of device is allocated dynamically. It
+needs to be freed when of_device_register() fails. Call put_device() to
+give up the reference that's taken in device_initialize(), so that it
+can be freed in kobject_cleanup() when the refcount hits 0.
+
+macio device is freed in macio_release_dev(), so the kfree() can be
+removed.
+
+Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20221104032551.1075335-1-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/macintosh/macio_asic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
+index 49af60bdac92..7db2e23a5ac8 100644
+--- a/drivers/macintosh/macio_asic.c
++++ b/drivers/macintosh/macio_asic.c
+@@ -425,7 +425,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
+       if (of_device_register(&dev->ofdev) != 0) {
+               printk(KERN_DEBUG"macio: device registration error for %s!\n",
+                      dev_name(&dev->ofdev.dev));
+-              kfree(dev);
++              put_device(&dev->ofdev.dev);
+               return NULL;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/macintosh-macio-adb-check-the-return-value-of-iorema.patch b/queue-5.10/macintosh-macio-adb-check-the-return-value-of-iorema.patch
new file mode 100644 (file)
index 0000000..7b8f1a0
--- /dev/null
@@ -0,0 +1,40 @@
+From 0b563d43589f4baebcb4aa1103837aa745c46d6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 15:41:48 +0800
+Subject: macintosh/macio-adb: check the return value of ioremap()
+
+From: Xie Shaowen <studentxswpy@163.com>
+
+[ Upstream commit dbaa3105736d4d73063ea0a3b01cd7fafce924e6 ]
+
+The function ioremap() in macio_init() can fail, so its return value
+should be checked.
+
+Fixes: 36874579dbf4c ("[PATCH] powerpc: macio-adb build fix")
+Reported-by: Hacash Robot <hacashRobot@santino.com>
+Signed-off-by: Xie Shaowen <studentxswpy@163.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220802074148.3213659-1-studentxswpy@163.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/macintosh/macio-adb.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c
+index d4759db002c6..defe65f51fa2 100644
+--- a/drivers/macintosh/macio-adb.c
++++ b/drivers/macintosh/macio-adb.c
+@@ -106,6 +106,10 @@ int macio_init(void)
+               return -ENXIO;
+       }
+       adb = ioremap(r.start, sizeof(struct adb_regs));
++      if (!adb) {
++              of_node_put(adbs);
++              return -ENOMEM;
++      }
+       out_8(&adb->ctrl.r, 0);
+       out_8(&adb->intr.r, 0);
+-- 
+2.35.1
+
diff --git a/queue-5.10/mailbox-zynq-ipi-fix-error-handling-while-device_reg.patch b/queue-5.10/mailbox-zynq-ipi-fix-error-handling-while-device_reg.patch
new file mode 100644 (file)
index 0000000..4171c23
--- /dev/null
@@ -0,0 +1,52 @@
+From 04d7073062d5baeebcb4056394bd072af6abaa16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 23:08:22 +0800
+Subject: mailbox: zynq-ipi: fix error handling while device_register() fails
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit a6792a0cdef0b1c2d77920246283a72537e60e94 ]
+
+If device_register() fails, it has two issues:
+1. The name allocated by dev_set_name() is leaked.
+2. The parent of device is not NULL, device_unregister() is called
+   in zynqmp_ipi_free_mboxes(), it will lead a kernel crash because
+   of removing not added device.
+
+Call put_device() to give up the reference, so the name is freed in
+kobject_cleanup(). Add device registered check in zynqmp_ipi_free_mboxes()
+to avoid null-ptr-deref.
+
+Fixes: 4981b82ba2ff ("mailbox: ZynqMP IPI mailbox controller")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/zynqmp-ipi-mailbox.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
+index f44079d62b1a..527204c6d5cd 100644
+--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
++++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
+@@ -493,6 +493,7 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
+       ret = device_register(&ipi_mbox->dev);
+       if (ret) {
+               dev_err(dev, "Failed to register ipi mbox dev.\n");
++              put_device(&ipi_mbox->dev);
+               return ret;
+       }
+       mdev = &ipi_mbox->dev;
+@@ -619,7 +620,8 @@ static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata)
+               ipi_mbox = &pdata->ipi_mboxes[i];
+               if (ipi_mbox->dev.parent) {
+                       mbox_controller_unregister(&ipi_mbox->mbox);
+-                      device_unregister(&ipi_mbox->dev);
++                      if (device_is_registered(&ipi_mbox->dev))
++                              device_unregister(&ipi_mbox->dev);
+               }
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/mcb-mcb-parse-fix-error-handing-in-chameleon_parse_g.patch b/queue-5.10/mcb-mcb-parse-fix-error-handing-in-chameleon_parse_g.patch
new file mode 100644 (file)
index 0000000..9f5f22f
--- /dev/null
@@ -0,0 +1,40 @@
+From 25e2917b5460f49b8c9dd4eb6ebdec634870aebb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 01:38:50 -0800
+Subject: mcb: mcb-parse: fix error handing in chameleon_parse_gdd()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 728ac3389296caf68638628c987aeae6c8851e2d ]
+
+If mcb_device_register() returns error in chameleon_parse_gdd(), the refcount
+of bus and device name are leaked. Fix this by calling put_device() to give up
+the reference, so they can be released in mcb_release_dev() and kobject_cleanup().
+
+Fixes: 3764e82e5150 ("drivers: Introduce MEN Chameleon Bus")
+Reviewed-by: Johannes Thumshirn <jth@kernel.org>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Johannes Thumshirn <jth@kernel.org>
+Link: https://lore.kernel.org/r/ebfb06e39b19272f0197fa9136b5e4b6f34ad732.1669624063.git.johannes.thumshirn@wdc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mcb/mcb-parse.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c
+index 0266bfddfbe2..aa6938da0db8 100644
+--- a/drivers/mcb/mcb-parse.c
++++ b/drivers/mcb/mcb-parse.c
+@@ -108,7 +108,7 @@ static int chameleon_parse_gdd(struct mcb_bus *bus,
+       return 0;
+ err:
+-      mcb_free_dev(mdev);
++      put_device(&mdev->dev);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/md-raid1-stop-mdx_raid1-thread-when-raid1-array-run-.patch b/queue-5.10/md-raid1-stop-mdx_raid1-thread-when-raid1-array-run-.patch
new file mode 100644 (file)
index 0000000..ac85c4b
--- /dev/null
@@ -0,0 +1,71 @@
+From 4c8ccc8268f23568947e91e3c8ed3165bd7b7f05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Nov 2022 22:16:59 +0800
+Subject: md/raid1: stop mdx_raid1 thread when raid1 array run failed
+
+From: Jiang Li <jiang.li@ugreen.com>
+
+[ Upstream commit b611ad14006e5be2170d9e8e611bf49dff288911 ]
+
+fail run raid1 array when we assemble array with the inactive disk only,
+but the mdx_raid1 thread were not stop, Even if the associated resources
+have been released. it will caused a NULL dereference when we do poweroff.
+
+This causes the following Oops:
+    [  287.587787] BUG: kernel NULL pointer dereference, address: 0000000000000070
+    [  287.594762] #PF: supervisor read access in kernel mode
+    [  287.599912] #PF: error_code(0x0000) - not-present page
+    [  287.605061] PGD 0 P4D 0
+    [  287.607612] Oops: 0000 [#1] SMP NOPTI
+    [  287.611287] CPU: 3 PID: 5265 Comm: md0_raid1 Tainted: G     U            5.10.146 #0
+    [  287.619029] Hardware name: xxxxxxx/To be filled by O.E.M, BIOS 5.19 06/16/2022
+    [  287.626775] RIP: 0010:md_check_recovery+0x57/0x500 [md_mod]
+    [  287.632357] Code: fe 01 00 00 48 83 bb 10 03 00 00 00 74 08 48 89 ......
+    [  287.651118] RSP: 0018:ffffc90000433d78 EFLAGS: 00010202
+    [  287.656347] RAX: 0000000000000000 RBX: ffff888105986800 RCX: 0000000000000000
+    [  287.663491] RDX: ffffc90000433bb0 RSI: 00000000ffffefff RDI: ffff888105986800
+    [  287.670634] RBP: ffffc90000433da0 R08: 0000000000000000 R09: c0000000ffffefff
+    [  287.677771] R10: 0000000000000001 R11: ffffc90000433ba8 R12: ffff888105986800
+    [  287.684907] R13: 0000000000000000 R14: fffffffffffffe00 R15: ffff888100b6b500
+    [  287.692052] FS:  0000000000000000(0000) GS:ffff888277f80000(0000) knlGS:0000000000000000
+    [  287.700149] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+    [  287.705897] CR2: 0000000000000070 CR3: 000000000320a000 CR4: 0000000000350ee0
+    [  287.713033] Call Trace:
+    [  287.715498]  raid1d+0x6c/0xbbb [raid1]
+    [  287.719256]  ? __schedule+0x1ff/0x760
+    [  287.722930]  ? schedule+0x3b/0xb0
+    [  287.726260]  ? schedule_timeout+0x1ed/0x290
+    [  287.730456]  ? __switch_to+0x11f/0x400
+    [  287.734219]  md_thread+0xe9/0x140 [md_mod]
+    [  287.738328]  ? md_thread+0xe9/0x140 [md_mod]
+    [  287.742601]  ? wait_woken+0x80/0x80
+    [  287.746097]  ? md_register_thread+0xe0/0xe0 [md_mod]
+    [  287.751064]  kthread+0x11a/0x140
+    [  287.754300]  ? kthread_park+0x90/0x90
+    [  287.757974]  ret_from_fork+0x1f/0x30
+
+In fact, when raid1 array run fail, we need to do
+md_unregister_thread() before raid1_free().
+
+Signed-off-by: Jiang Li <jiang.li@ugreen.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid1.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index fb31e5dd54a6..6b5cc3f59fb3 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -3115,6 +3115,7 @@ static int raid1_run(struct mddev *mddev)
+        * RAID1 needs at least one disk in active
+        */
+       if (conf->raid_disks - mddev->degraded < 1) {
++              md_unregister_thread(&conf->thread);
+               ret = -EINVAL;
+               goto abort;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-c8sectpfe-add-of_node_put-when-breaking-out-of.patch b/queue-5.10/media-c8sectpfe-add-of_node_put-when-breaking-out-of.patch
new file mode 100644 (file)
index 0000000..0e52954
--- /dev/null
@@ -0,0 +1,36 @@
+From f49188704cf2d24c4661a3fc4527de3dc8e5c5f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 22:10:23 +0800
+Subject: media: c8sectpfe: Add of_node_put() when breaking out of loop
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 63ff05a1ad242a5a0f897921c87b70d601bda59c ]
+
+In configure_channels(), we should call of_node_put() when breaking
+out of for_each_child_of_node() which will automatically increase
+and decrease the refcount.
+
+Fixes: c5f5d0f99794 ("[media] c8sectpfe: STiH407/10 Linux DVB demux support")
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+index dbe7788083a4..b7e0ec265b70 100644
+--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
++++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+@@ -937,6 +937,7 @@ static int configure_channels(struct c8sectpfei *fei)
+               if (ret) {
+                       dev_err(fei->dev,
+                               "configure_memdma_and_inputblock failed\n");
++                      of_node_put(child);
+                       goto err_unmap;
+               }
+               index++;
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-camss-clean-up-received-buffers-on-failed-star.patch b/queue-5.10/media-camss-clean-up-received-buffers-on-failed-star.patch
new file mode 100644 (file)
index 0000000..972b295
--- /dev/null
@@ -0,0 +1,62 @@
+From 9d41042e37642dfa67c3659a33d8a52f0dbbafab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Jul 2022 10:44:37 +0100
+Subject: media: camss: Clean up received buffers on failed start of streaming
+
+From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+
+[ Upstream commit c8f3582345e6a69da65ab588f7c4c2d1685b0e80 ]
+
+It is required to return the received buffers, if streaming can not be
+started. For instance media_pipeline_start() may fail with EPIPE, if
+a link validation between entities is not passed, and in such a case
+a user gets a kernel warning:
+
+  WARNING: CPU: 1 PID: 520 at drivers/media/common/videobuf2/videobuf2-core.c:1592 vb2_start_streaming+0xec/0x160
+  <snip>
+  Call trace:
+   vb2_start_streaming+0xec/0x160
+   vb2_core_streamon+0x9c/0x1a0
+   vb2_ioctl_streamon+0x68/0xbc
+   v4l_streamon+0x30/0x3c
+   __video_do_ioctl+0x184/0x3e0
+   video_usercopy+0x37c/0x7b0
+   video_ioctl2+0x24/0x40
+   v4l2_ioctl+0x4c/0x70
+
+The fix is to correct the error path in video_start_streaming() of camss.
+
+Fixes: 0ac2586c410f ("media: camss: Add files which handle the video device nodes")
+Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/camss/camss-video.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
+index 15965e63cb61..9333a7a33d4d 100644
+--- a/drivers/media/platform/qcom/camss/camss-video.c
++++ b/drivers/media/platform/qcom/camss/camss-video.c
+@@ -444,7 +444,7 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
+       ret = media_pipeline_start(&vdev->entity, &video->pipe);
+       if (ret < 0)
+-              return ret;
++              goto flush_buffers;
+       ret = video_check_format(video);
+       if (ret < 0)
+@@ -473,6 +473,7 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
+ error:
+       media_pipeline_stop(&vdev->entity);
++flush_buffers:
+       video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
+       return ret;
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-coda-add-check-for-dcoda_iram_alloc.patch b/queue-5.10/media-coda-add-check-for-dcoda_iram_alloc.patch
new file mode 100644 (file)
index 0000000..599756c
--- /dev/null
@@ -0,0 +1,47 @@
+From dbde116e49aacf51cfa19f2c1015b18a002b46f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 14:56:52 +0800
+Subject: media: coda: Add check for dcoda_iram_alloc
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 6b8082238fb8bb20f67e46388123e67a5bbc558d ]
+
+As the coda_iram_alloc may return NULL pointer,
+it should be better to check the return value
+in order to avoid NULL poineter dereference,
+same as the others.
+
+Fixes: b313bcc9a467 ("[media] coda: simplify IRAM setup")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/coda/coda-bit.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
+index 159c9de85788..b8a70ef8e8ec 100644
+--- a/drivers/media/platform/coda/coda-bit.c
++++ b/drivers/media/platform/coda/coda-bit.c
+@@ -852,7 +852,7 @@ static void coda_setup_iram(struct coda_ctx *ctx)
+               /* Only H.264BP and H.263P3 are considered */
+               iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, w64);
+               iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, w64);
+-              if (!iram_info->buf_dbk_c_use)
++              if (!iram_info->buf_dbk_y_use || !iram_info->buf_dbk_c_use)
+                       goto out;
+               iram_info->axi_sram_use |= dbk_bits;
+@@ -876,7 +876,7 @@ static void coda_setup_iram(struct coda_ctx *ctx)
+               iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, w128);
+               iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, w128);
+-              if (!iram_info->buf_dbk_c_use)
++              if (!iram_info->buf_dbk_y_use || !iram_info->buf_dbk_c_use)
+                       goto out;
+               iram_info->axi_sram_use |= dbk_bits;
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-coda-add-check-for-kmalloc.patch b/queue-5.10/media-coda-add-check-for-kmalloc.patch
new file mode 100644 (file)
index 0000000..be29c7d
--- /dev/null
@@ -0,0 +1,48 @@
+From 24427d610ca3c746238e224cd9b5e65f83de00aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 15:02:36 +0800
+Subject: media: coda: Add check for kmalloc
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 6e5e5defdb8b0186312c2f855ace175aee6daf9b ]
+
+As the kmalloc may return NULL pointer,
+it should be better to check the return value
+in order to avoid NULL poineter dereference,
+same as the others.
+
+Fixes: cb1d3a336371 ("[media] coda: add CODA7541 JPEG support")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/coda/coda-bit.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
+index b8a70ef8e8ec..6ffa12e83e42 100644
+--- a/drivers/media/platform/coda/coda-bit.c
++++ b/drivers/media/platform/coda/coda-bit.c
+@@ -1082,10 +1082,16 @@ static int coda_start_encoding(struct coda_ctx *ctx)
+       }
+       if (dst_fourcc == V4L2_PIX_FMT_JPEG) {
+-              if (!ctx->params.jpeg_qmat_tab[0])
++              if (!ctx->params.jpeg_qmat_tab[0]) {
+                       ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL);
+-              if (!ctx->params.jpeg_qmat_tab[1])
++                      if (!ctx->params.jpeg_qmat_tab[0])
++                              return -ENOMEM;
++              }
++              if (!ctx->params.jpeg_qmat_tab[1]) {
+                       ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL);
++                      if (!ctx->params.jpeg_qmat_tab[1])
++                              return -ENOMEM;
++              }
+               coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-coda-jpeg-add-check-for-kmalloc.patch b/queue-5.10/media-coda-jpeg-add-check-for-kmalloc.patch
new file mode 100644 (file)
index 0000000..7040533
--- /dev/null
@@ -0,0 +1,47 @@
+From c047e20fee855595b4c5954c842aa614754bcf99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Sep 2022 09:28:13 +0800
+Subject: media: coda: jpeg: Add check for kmalloc
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit f30ce3d3760b22ee33c8d9c2e223764ad30bdc5f ]
+
+As kmalloc can return NULL pointer, it should be better to
+check the return value and return error, same as
+coda_jpeg_decode_header.
+
+Fixes: 96f6f62c4656 ("media: coda: jpeg: add CODA960 JPEG encoder support")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/coda/coda-jpeg.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/coda/coda-jpeg.c b/drivers/media/platform/coda/coda-jpeg.c
+index a72f4655e5ad..b7bf529f18f7 100644
+--- a/drivers/media/platform/coda/coda-jpeg.c
++++ b/drivers/media/platform/coda/coda-jpeg.c
+@@ -1052,10 +1052,16 @@ static int coda9_jpeg_start_encoding(struct coda_ctx *ctx)
+               v4l2_err(&dev->v4l2_dev, "error loading Huffman tables\n");
+               return ret;
+       }
+-      if (!ctx->params.jpeg_qmat_tab[0])
++      if (!ctx->params.jpeg_qmat_tab[0]) {
+               ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL);
+-      if (!ctx->params.jpeg_qmat_tab[1])
++              if (!ctx->params.jpeg_qmat_tab[0])
++                      return -ENOMEM;
++      }
++      if (!ctx->params.jpeg_qmat_tab[1]) {
+               ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL);
++              if (!ctx->params.jpeg_qmat_tab[1])
++                      return -ENOMEM;
++      }
+       coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality);
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-dvb-core-fix-ignored-return-value-in-dvb_regis.patch b/queue-5.10/media-dvb-core-fix-ignored-return-value-in-dvb_regis.patch
new file mode 100644 (file)
index 0000000..777f6ee
--- /dev/null
@@ -0,0 +1,71 @@
+From 3d8cca9672c9803da078e31a0a167aee482381fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 03:30:05 +0000
+Subject: media: dvb-core: Fix ignored return value in dvb_register_frontend()
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit a574359e2e71ce16be212df3a082ed60a4bd2c5f ]
+
+In dvb_register_frontend(), dvb_register_device() is possible to fail
+but its return value is ignored.
+
+It will cause use-after-free when module is removed, because in
+dvb_unregister_frontend() it tries to unregister a not registered
+device.
+
+BUG: KASAN: use-after-free in dvb_remove_device+0x18b/0x1f0 [dvb_core]
+Read of size 4 at addr ffff88800dff4824 by task rmmod/428
+CPU: 3 PID: 428 Comm: rmmod
+Call Trace:
+ <TASK>
+ ...
+ dvb_remove_device+0x18b/0x1f0 [dvb_core]
+ dvb_unregister_frontend+0x7b/0x130 [dvb_core]
+ vidtv_bridge_remove+0x6e/0x160 [dvb_vidtv_bridge]
+ ...
+
+Fix this by catching return value of dvb_register_device().
+However the fe->refcount can't be put to zero immediately, because
+there are still modules calling dvb_frontend_detach() when
+dvb_register_frontend() fails.
+
+Link: https://lore.kernel.org/linux-media/20221108033005.169095-1-chenzhongjin@huawei.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-core/dvb_frontend.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
+index 06ea30a689d7..b28ea7204f23 100644
+--- a/drivers/media/dvb-core/dvb_frontend.c
++++ b/drivers/media/dvb-core/dvb_frontend.c
+@@ -2961,6 +2961,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
+               .name = fe->ops.info.name,
+ #endif
+       };
++      int ret;
+       dev_dbg(dvb->device, "%s:\n", __func__);
+@@ -2994,8 +2995,13 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
+                "DVB: registering adapter %i frontend %i (%s)...\n",
+                fe->dvb->num, fe->id, fe->ops.info.name);
+-      dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
++      ret = dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
+                           fe, DVB_DEVICE_FRONTEND, 0);
++      if (ret) {
++              dvb_frontend_put(fe);
++              mutex_unlock(&frontend_mutex);
++              return ret;
++      }
+       /*
+        * Initialize the cache to the proper values according with the
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-dvb-frontends-fix-leak-of-memory-fw.patch b/queue-5.10/media-dvb-frontends-fix-leak-of-memory-fw.patch
new file mode 100644 (file)
index 0000000..16cd738
--- /dev/null
@@ -0,0 +1,32 @@
+From e8cc469fef1f69257c95166f36a398ac34edbe2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Apr 2022 07:19:25 +0100
+Subject: media: dvb-frontends: fix leak of memory fw
+
+From: Yan Lei <yan_lei@dahuatech.com>
+
+[ Upstream commit a15fe8d9f1bf460a804bcf18a890bfd2cf0d5caa ]
+
+Link: https://lore.kernel.org/linux-media/20220410061925.4107-1-chinayanlei2002@163.com
+Signed-off-by: Yan Lei <yan_lei@dahuatech.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-frontends/bcm3510.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c
+index da0ff7b44da4..68b92b4419cf 100644
+--- a/drivers/media/dvb-frontends/bcm3510.c
++++ b/drivers/media/dvb-frontends/bcm3510.c
+@@ -649,6 +649,7 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe)
+               deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
+               if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
+                       err("firmware download failed: %d\n",ret);
++                      release_firmware(fw);
+                       return ret;
+               }
+               i += 4 + len;
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-dvb-usb-az6027-fix-null-ptr-deref-in-az6027_i2.patch b/queue-5.10/media-dvb-usb-az6027-fix-null-ptr-deref-in-az6027_i2.patch
new file mode 100644 (file)
index 0000000..4cfb515
--- /dev/null
@@ -0,0 +1,64 @@
+From f8fd7925451bcc8619ac4c84987064561cd7025c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Nov 2022 06:59:18 +0000
+Subject: media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()
+
+From: Baisong Zhong <zhongbaisong@huawei.com>
+
+[ Upstream commit 0ed554fd769a19ea8464bb83e9ac201002ef74ad ]
+
+Wei Chen reports a kernel bug as blew:
+
+general protection fault, probably for non-canonical address
+KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
+...
+Call Trace:
+<TASK>
+__i2c_transfer+0x77e/0x1930 drivers/i2c/i2c-core-base.c:2109
+i2c_transfer+0x1d5/0x3d0 drivers/i2c/i2c-core-base.c:2170
+i2cdev_ioctl_rdwr+0x393/0x660 drivers/i2c/i2c-dev.c:297
+i2cdev_ioctl+0x75d/0x9f0 drivers/i2c/i2c-dev.c:458
+vfs_ioctl fs/ioctl.c:51 [inline]
+__do_sys_ioctl fs/ioctl.c:870 [inline]
+__se_sys_ioctl+0xfb/0x170 fs/ioctl.c:856
+do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+do_syscall_64+0x3d/0x90 arch/x86/entry/common.c:80
+entry_SYSCALL_64_after_hwframe+0x63/0xcd
+RIP: 0033:0x7fd834a8bded
+
+In az6027_i2c_xfer(), if msg[i].addr is 0x99,
+a null-ptr-deref will caused when accessing msg[i].buf.
+For msg[i].len is 0 and msg[i].buf is null.
+
+Fix this by checking msg[i].len in az6027_i2c_xfer().
+
+Link: https://lore.kernel.org/lkml/CAO4mrfcPHB5aQJO=mpqV+p8mPLNg-Fok0gw8gZ=zemAfMGTzMg@mail.gmail.com/
+
+Link: https://lore.kernel.org/linux-media/20221120065918.2160782-1-zhongbaisong@huawei.com
+Fixes: 76f9a820c867 ("V4L/DVB: AZ6027: Initial import of the driver")
+Reported-by: Wei Chen <harperchen1110@gmail.com>
+Signed-off-by: Baisong Zhong <zhongbaisong@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb/az6027.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
+index 86788771175b..32b4ee65c280 100644
+--- a/drivers/media/usb/dvb-usb/az6027.c
++++ b/drivers/media/usb/dvb-usb/az6027.c
+@@ -975,6 +975,10 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
+               if (msg[i].addr == 0x99) {
+                       req = 0xBE;
+                       index = 0;
++                      if (msg[i].len < 1) {
++                              i = -EOPNOTSUPP;
++                              break;
++                      }
+                       value = msg[i].buf[0] & 0x00ff;
+                       length = 1;
+                       az6027_usb_out_op(d, req, value, index, data, length);
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-dvb-usb-fix-memory-leak-in-dvb_usb_adapter_ini.patch b/queue-5.10/media-dvb-usb-fix-memory-leak-in-dvb_usb_adapter_ini.patch
new file mode 100644 (file)
index 0000000..aaf7be1
--- /dev/null
@@ -0,0 +1,97 @@
+From 2ac00b8e8caf0525470a3a20cd97e2d452c43446 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Aug 2022 02:21:52 +0100
+Subject: media: dvb-usb: fix memory leak in dvb_usb_adapter_init()
+
+From: Mazin Al Haddad <mazinalhaddad05@gmail.com>
+
+[ Upstream commit 94d90fb06b94a90c176270d38861bcba34ce377d ]
+
+Syzbot reports a memory leak in "dvb_usb_adapter_init()".
+The leak is due to not accounting for and freeing current iteration's
+adapter->priv in case of an error. Currently if an error occurs,
+it will exit before incrementing "num_adapters_initalized",
+which is used as a reference counter to free all adap->priv
+in "dvb_usb_adapter_exit()". There are multiple error paths that
+can exit from before incrementing the counter. Including the
+error handling paths for "dvb_usb_adapter_stream_init()",
+"dvb_usb_adapter_dvb_init()" and "dvb_usb_adapter_frontend_init()"
+within "dvb_usb_adapter_init()".
+
+This means that in case of an error in any of these functions the
+current iteration is not accounted for and the current iteration's
+adap->priv is not freed.
+
+Fix this by freeing the current iteration's adap->priv in the
+"stream_init_err:" label in the error path. The rest of the
+(accounted for) adap->priv objects are freed in dvb_usb_adapter_exit()
+as expected using the num_adapters_initalized variable.
+
+Syzbot report:
+
+BUG: memory leak
+unreferenced object 0xffff8881172f1a00 (size 512):
+  comm "kworker/0:2", pid 139, jiffies 4294994873 (age 10.960s)
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+backtrace:
+    [<ffffffff844af012>] dvb_usb_adapter_init drivers/media/usb/dvb-usb/dvb-usb-init.c:75 [inline]
+    [<ffffffff844af012>] dvb_usb_init drivers/media/usb/dvb-usb/dvb-usb-init.c:184 [inline]
+    [<ffffffff844af012>] dvb_usb_device_init.cold+0x4e5/0x79e drivers/media/usb/dvb-usb/dvb-usb-init.c:308
+    [<ffffffff830db21d>] dib0700_probe+0x8d/0x1b0 drivers/media/usb/dvb-usb/dib0700_core.c:883
+    [<ffffffff82d3fdc7>] usb_probe_interface+0x177/0x370 drivers/usb/core/driver.c:396
+    [<ffffffff8274ab37>] call_driver_probe drivers/base/dd.c:542 [inline]
+    [<ffffffff8274ab37>] really_probe.part.0+0xe7/0x310 drivers/base/dd.c:621
+    [<ffffffff8274ae6c>] really_probe drivers/base/dd.c:583 [inline]
+    [<ffffffff8274ae6c>] __driver_probe_device+0x10c/0x1e0 drivers/base/dd.c:752
+    [<ffffffff8274af6a>] driver_probe_device+0x2a/0x120 drivers/base/dd.c:782
+    [<ffffffff8274b786>] __device_attach_driver+0xf6/0x140 drivers/base/dd.c:899
+    [<ffffffff82747c87>] bus_for_each_drv+0xb7/0x100 drivers/base/bus.c:427
+    [<ffffffff8274b352>] __device_attach+0x122/0x260 drivers/base/dd.c:970
+    [<ffffffff827498f6>] bus_probe_device+0xc6/0xe0 drivers/base/bus.c:487
+    [<ffffffff82745cdb>] device_add+0x5fb/0xdf0 drivers/base/core.c:3405
+    [<ffffffff82d3d202>] usb_set_configuration+0x8f2/0xb80 drivers/usb/core/message.c:2170
+    [<ffffffff82d4dbfc>] usb_generic_driver_probe+0x8c/0xc0 drivers/usb/core/generic.c:238
+    [<ffffffff82d3f49c>] usb_probe_device+0x5c/0x140 drivers/usb/core/driver.c:293
+    [<ffffffff8274ab37>] call_driver_probe drivers/base/dd.c:542 [inline]
+    [<ffffffff8274ab37>] really_probe.part.0+0xe7/0x310 drivers/base/dd.c:621
+    [<ffffffff8274ae6c>] really_probe drivers/base/dd.c:583 [inline]
+    [<ffffffff8274ae6c>] __driver_probe_device+0x10c/0x1e0 drivers/base/dd.c:752
+
+Link: https://syzkaller.appspot.com/bug?extid=f66dd31987e6740657be
+Reported-and-tested-by: syzbot+f66dd31987e6740657be@syzkaller.appspotmail.com
+
+Link: https://lore.kernel.org/linux-media/20220824012152.539788-1-mazinalhaddad05@gmail.com
+Signed-off-by: Mazin Al Haddad <mazinalhaddad05@gmail.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb/dvb-usb-init.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
+index 61439c8f33ca..58eea8ab5477 100644
+--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c
++++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
+@@ -81,7 +81,7 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
+               ret = dvb_usb_adapter_stream_init(adap);
+               if (ret)
+-                      return ret;
++                      goto stream_init_err;
+               ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs);
+               if (ret)
+@@ -114,6 +114,8 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
+       dvb_usb_adapter_dvb_exit(adap);
+ dvb_init_err:
+       dvb_usb_adapter_stream_exit(adap);
++stream_init_err:
++      kfree(adap->priv);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-dvbdev-adopts-refcnt-to-avoid-uaf.patch b/queue-5.10/media-dvbdev-adopts-refcnt-to-avoid-uaf.patch
new file mode 100644 (file)
index 0000000..bbba30d
--- /dev/null
@@ -0,0 +1,210 @@
+From 50cd74368bac90cb073472e05240ebae0f449e38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Aug 2022 15:59:52 +0100
+Subject: media: dvbdev: adopts refcnt to avoid UAF
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit 0fc044b2b5e2d05a1fa1fb0d7f270367a7855d79 ]
+
+dvb_unregister_device() is known that prone to use-after-free.
+That is, the cleanup from dvb_unregister_device() releases the dvb_device
+even if there are pointers stored in file->private_data still refer to it.
+
+This patch adds a reference counter into struct dvb_device and delays its
+deallocation until no pointer refers to the object.
+
+Link: https://lore.kernel.org/linux-media/20220807145952.10368-1-linma@zju.edu.cn
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-core/dvb_ca_en50221.c |  2 +-
+ drivers/media/dvb-core/dvb_frontend.c   |  2 +-
+ drivers/media/dvb-core/dvbdev.c         | 32 +++++++++++++++++++------
+ include/media/dvbdev.h                  | 31 +++++++++++++-----------
+ 4 files changed, 44 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
+index cfc27629444f..fd476536d32e 100644
+--- a/drivers/media/dvb-core/dvb_ca_en50221.c
++++ b/drivers/media/dvb-core/dvb_ca_en50221.c
+@@ -157,7 +157,7 @@ static void dvb_ca_private_free(struct dvb_ca_private *ca)
+ {
+       unsigned int i;
+-      dvb_free_device(ca->dvbdev);
++      dvb_device_put(ca->dvbdev);
+       for (i = 0; i < ca->slot_count; i++)
+               vfree(ca->slot_info[i].rx_buffer.data);
+diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
+index b28ea7204f23..b04638321b75 100644
+--- a/drivers/media/dvb-core/dvb_frontend.c
++++ b/drivers/media/dvb-core/dvb_frontend.c
+@@ -135,7 +135,7 @@ static void __dvb_frontend_free(struct dvb_frontend *fe)
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
+       if (fepriv)
+-              dvb_free_device(fepriv->dvbdev);
++              dvb_device_put(fepriv->dvbdev);
+       dvb_frontend_invoke_release(fe, fe->ops.release);
+diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
+index ec9ebff28552..7b28b483e4b2 100644
+--- a/drivers/media/dvb-core/dvbdev.c
++++ b/drivers/media/dvb-core/dvbdev.c
+@@ -107,7 +107,7 @@ static int dvb_device_open(struct inode *inode, struct file *file)
+               new_fops = fops_get(dvbdev->fops);
+               if (!new_fops)
+                       goto fail;
+-              file->private_data = dvbdev;
++              file->private_data = dvb_device_get(dvbdev);
+               replace_fops(file, new_fops);
+               if (file->f_op->open)
+                       err = file->f_op->open(inode, file);
+@@ -171,6 +171,9 @@ int dvb_generic_release(struct inode *inode, struct file *file)
+       }
+       dvbdev->users++;
++
++      dvb_device_put(dvbdev);
++
+       return 0;
+ }
+ EXPORT_SYMBOL(dvb_generic_release);
+@@ -487,6 +490,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+               return -ENOMEM;
+       }
++      kref_init(&dvbdev->ref);
+       memcpy(dvbdev, template, sizeof(struct dvb_device));
+       dvbdev->type = type;
+       dvbdev->id = id;
+@@ -517,7 +521,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ #endif
+       dvbdev->minor = minor;
+-      dvb_minors[minor] = dvbdev;
++      dvb_minors[minor] = dvb_device_get(dvbdev);
+       up_write(&minor_rwsem);
+       ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
+@@ -557,6 +561,7 @@ void dvb_remove_device(struct dvb_device *dvbdev)
+       down_write(&minor_rwsem);
+       dvb_minors[dvbdev->minor] = NULL;
++      dvb_device_put(dvbdev);
+       up_write(&minor_rwsem);
+       dvb_media_device_free(dvbdev);
+@@ -568,21 +573,34 @@ void dvb_remove_device(struct dvb_device *dvbdev)
+ EXPORT_SYMBOL(dvb_remove_device);
+-void dvb_free_device(struct dvb_device *dvbdev)
++static void dvb_free_device(struct kref *ref)
+ {
+-      if (!dvbdev)
+-              return;
++      struct dvb_device *dvbdev = container_of(ref, struct dvb_device, ref);
+       kfree (dvbdev->fops);
+       kfree (dvbdev);
+ }
+-EXPORT_SYMBOL(dvb_free_device);
++
++
++struct dvb_device *dvb_device_get(struct dvb_device *dvbdev)
++{
++      kref_get(&dvbdev->ref);
++      return dvbdev;
++}
++EXPORT_SYMBOL(dvb_device_get);
++
++
++void dvb_device_put(struct dvb_device *dvbdev)
++{
++      if (dvbdev)
++              kref_put(&dvbdev->ref, dvb_free_device);
++}
+ void dvb_unregister_device(struct dvb_device *dvbdev)
+ {
+       dvb_remove_device(dvbdev);
+-      dvb_free_device(dvbdev);
++      dvb_device_put(dvbdev);
+ }
+ EXPORT_SYMBOL(dvb_unregister_device);
+diff --git a/include/media/dvbdev.h b/include/media/dvbdev.h
+index e547cbeee431..6e736587aa1f 100644
+--- a/include/media/dvbdev.h
++++ b/include/media/dvbdev.h
+@@ -156,6 +156,7 @@ struct dvb_adapter {
+  */
+ struct dvb_device {
+       struct list_head list_head;
++      struct kref ref;
+       const struct file_operations *fops;
+       struct dvb_adapter *adapter;
+       enum dvb_device_type type;
+@@ -187,6 +188,20 @@ struct dvb_device {
+       void *priv;
+ };
++/**
++ * dvb_device_get - Increase dvb_device reference
++ *
++ * @dvbdev:   pointer to struct dvb_device
++ */
++struct dvb_device *dvb_device_get(struct dvb_device *dvbdev);
++
++/**
++ * dvb_device_get - Decrease dvb_device reference
++ *
++ * @dvbdev:   pointer to struct dvb_device
++ */
++void dvb_device_put(struct dvb_device *dvbdev);
++
+ /**
+  * dvb_register_adapter - Registers a new DVB adapter
+  *
+@@ -231,29 +246,17 @@ int dvb_register_device(struct dvb_adapter *adap,
+ /**
+  * dvb_remove_device - Remove a registered DVB device
+  *
+- * This does not free memory.  To do that, call dvb_free_device().
++ * This does not free memory. dvb_free_device() will do that when
++ * reference counter is empty
+  *
+  * @dvbdev:   pointer to struct dvb_device
+  */
+ void dvb_remove_device(struct dvb_device *dvbdev);
+-/**
+- * dvb_free_device - Free memory occupied by a DVB device.
+- *
+- * Call dvb_unregister_device() before calling this function.
+- *
+- * @dvbdev:   pointer to struct dvb_device
+- */
+-void dvb_free_device(struct dvb_device *dvbdev);
+ /**
+  * dvb_unregister_device - Unregisters a DVB device
+  *
+- * This is a combination of dvb_remove_device() and dvb_free_device().
+- * Using this function is usually a mistake, and is often an indicator
+- * for a use-after-free bug (when a userspace process keeps a file
+- * handle to a detached device).
+- *
+  * @dvbdev:   pointer to struct dvb_device
+  */
+ void dvb_unregister_device(struct dvb_device *dvbdev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-exynos4-is-don-t-rely-on-the-v4l2_async_subdev.patch b/queue-5.10/media-exynos4-is-don-t-rely-on-the-v4l2_async_subdev.patch
new file mode 100644 (file)
index 0000000..b190ac6
--- /dev/null
@@ -0,0 +1,45 @@
+From 16f6d9c174885ff7282701e32d5ac860791d4cf5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Sep 2022 11:42:01 +0200
+Subject: media: exynos4-is: don't rely on the v4l2_async_subdev internals
+
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+
+[ Upstream commit f98a5c2e1c4396488c27274ba82afc11725a4bcc ]
+
+Commit 1f391df44607 ("media: v4l2-async: Use endpoints in
+__v4l2_async_nf_add_fwnode_remote()") changed the data that is stored in
+the v4l2_async_subdev internals from the fwnode pointer to the parent
+device to the fwnode pointer to the matched endpoint. This broke the
+sensor matching code, which relied on the particular fwnode data in the
+v4l2_async_subdev internals. Fix this by simply matching the
+v4l2_async_subdev pointer, which is already available there.
+
+Reported-by: Daniel Scally <djrscally@gmail.com>
+Fixes: fa91f1056f17 ("[media] exynos4-is: Add support for asynchronous subdevices registration")
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Reviewed-by: Daniel Scally <djrscally@gmail.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 3d877c5ae290..8603c578f55f 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1378,9 +1378,7 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+       /* Find platform data for this sensor subdev */
+       for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
+-              if (fmd->sensor[i].asd &&
+-                  fmd->sensor[i].asd->match.fwnode ==
+-                  of_fwnode_handle(subdev->dev->of_node))
++              if (fmd->sensor[i].asd == asd)
+                       si = &fmd->sensor[i];
+       if (si == NULL)
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-exynos4-is-use-v4l2_async_notifier_add_fwnode_.patch b/queue-5.10/media-exynos4-is-use-v4l2_async_notifier_add_fwnode_.patch
new file mode 100644 (file)
index 0000000..016fe38
--- /dev/null
@@ -0,0 +1,119 @@
+From d4b161e8c74444a52da9a975be084282a74563e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jan 2021 02:52:48 +0100
+Subject: media: exynos4-is: Use v4l2_async_notifier_add_fwnode_remote_subdev
+
+From: Ezequiel Garcia <ezequiel@collabora.com>
+
+[ Upstream commit 3a2822bfe45c50abd9f76a8547a77a1f6a0e8c8d ]
+
+The use of v4l2_async_notifier_add_subdev will be discouraged.
+Drivers are instead encouraged to use a helper such as
+v4l2_async_notifier_add_fwnode_remote_subdev.
+
+This fixes a misuse of the API, as v4l2_async_notifier_add_subdev
+should get a kmalloc'ed struct v4l2_async_subdev,
+removing some boilerplate code while at it.
+
+Use the appropriate helper v4l2_async_notifier_add_fwnode_remote_subdev,
+which handles the needed setup, instead of open-coding it.
+
+Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
+Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Reviewed-by: Helen Koike <helen.koike@collabora.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f98a5c2e1c43 ("media: exynos4-is: don't rely on the v4l2_async_subdev internals")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 24 ++++++++++---------
+ drivers/media/platform/exynos4-is/media-dev.h |  2 +-
+ 2 files changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index a9a8f0433fb2..3d877c5ae290 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -401,6 +401,7 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd,
+       int index = fmd->num_sensors;
+       struct fimc_source_info *pd = &fmd->sensor[index].pdata;
+       struct device_node *rem, *np;
++      struct v4l2_async_subdev *asd;
+       struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
+       int ret;
+@@ -418,10 +419,10 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd,
+       pd->mux_id = (endpoint.base.port - 1) & 0x1;
+       rem = of_graph_get_remote_port_parent(ep);
+-      of_node_put(ep);
+       if (rem == NULL) {
+               v4l2_info(&fmd->v4l2_dev, "Remote device at %pOF not found\n",
+                                                       ep);
++              of_node_put(ep);
+               return 0;
+       }
+@@ -450,6 +451,7 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd,
+        * checking parent's node name.
+        */
+       np = of_get_parent(rem);
++      of_node_put(rem);
+       if (of_node_name_eq(np, "i2c-isp"))
+               pd->fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK;
+@@ -458,20 +460,19 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd,
+       of_node_put(np);
+       if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor))) {
+-              of_node_put(rem);
++              of_node_put(ep);
+               return -EINVAL;
+       }
+-      fmd->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+-      fmd->sensor[index].asd.match.fwnode = of_fwnode_handle(rem);
++      asd = v4l2_async_notifier_add_fwnode_remote_subdev(
++              &fmd->subdev_notifier, of_fwnode_handle(ep), sizeof(*asd));
+-      ret = v4l2_async_notifier_add_subdev(&fmd->subdev_notifier,
+-                                           &fmd->sensor[index].asd);
+-      if (ret) {
+-              of_node_put(rem);
+-              return ret;
+-      }
++      of_node_put(ep);
++
++      if (IS_ERR(asd))
++              return PTR_ERR(asd);
++      fmd->sensor[index].asd = asd;
+       fmd->num_sensors++;
+       return 0;
+@@ -1377,7 +1378,8 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+       /* Find platform data for this sensor subdev */
+       for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
+-              if (fmd->sensor[i].asd.match.fwnode ==
++              if (fmd->sensor[i].asd &&
++                  fmd->sensor[i].asd->match.fwnode ==
+                   of_fwnode_handle(subdev->dev->of_node))
+                       si = &fmd->sensor[i];
+diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
+index 9447fafe23c6..a3876d668ea6 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.h
++++ b/drivers/media/platform/exynos4-is/media-dev.h
+@@ -83,7 +83,7 @@ struct fimc_camclk_info {
+  */
+ struct fimc_sensor_info {
+       struct fimc_source_info pdata;
+-      struct v4l2_async_subdev asd;
++      struct v4l2_async_subdev *asd;
+       struct v4l2_subdev *subdev;
+       struct fimc_dev *host;
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-i2c-ad5820-fix-error-path.patch b/queue-5.10/media-i2c-ad5820-fix-error-path.patch
new file mode 100644 (file)
index 0000000..2da6315
--- /dev/null
@@ -0,0 +1,51 @@
+From 7e51ed2c9a652814b8b2485b5efc6a41f0f5bacf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Sep 2022 13:38:00 +0200
+Subject: media: i2c: ad5820: Fix error path
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+[ Upstream commit 9fce241660f37d9e95e93c0ae6fba8cfefa5797b ]
+
+Error path seems to be swaped. Fix the order and provide some meaningful
+names.
+
+Fixes: bee3d5115611 ("[media] ad5820: Add driver for auto-focus coil")
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ad5820.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c
+index 19c74db0649f..f55322eebf6d 100644
+--- a/drivers/media/i2c/ad5820.c
++++ b/drivers/media/i2c/ad5820.c
+@@ -329,18 +329,18 @@ static int ad5820_probe(struct i2c_client *client,
+       ret = media_entity_pads_init(&coil->subdev.entity, 0, NULL);
+       if (ret < 0)
+-              goto cleanup2;
++              goto clean_mutex;
+       ret = v4l2_async_register_subdev(&coil->subdev);
+       if (ret < 0)
+-              goto cleanup;
++              goto clean_entity;
+       return ret;
+-cleanup2:
+-      mutex_destroy(&coil->power_lock);
+-cleanup:
++clean_entity:
+       media_entity_cleanup(&coil->subdev.entity);
++clean_mutex:
++      mutex_destroy(&coil->power_lock);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-imon-fix-a-race-condition-in-send_packet.patch b/queue-5.10/media-imon-fix-a-race-condition-in-send_packet.patch
new file mode 100644 (file)
index 0000000..72e47be
--- /dev/null
@@ -0,0 +1,79 @@
+From 01a88de0109b797db8f5a67a8edf1e880ccf46e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Oct 2022 06:02:14 +0100
+Subject: media: imon: fix a race condition in send_packet()
+
+From: Gautam Menghani <gautammenghani201@gmail.com>
+
+[ Upstream commit 813ceef062b53d68f296aa3cb944b21a091fabdb ]
+
+The function send_packet() has a race condition as follows:
+
+func send_packet()
+{
+    // do work
+    call usb_submit_urb()
+    mutex_unlock()
+    wait_for_event_interruptible()  <-- lock gone
+    mutex_lock()
+}
+
+func vfd_write()
+{
+    mutex_lock()
+    call send_packet()  <- prev call is not completed
+    mutex_unlock()
+}
+
+When the mutex is unlocked and the function send_packet() waits for the
+call to complete, vfd_write() can start another call, which leads to the
+"URB submitted while active" warning in usb_submit_urb().
+Fix this by removing the mutex_unlock() call in send_packet() and using
+mutex_lock_interruptible().
+
+Link: https://syzkaller.appspot.com/bug?id=e378e6a51fbe6c5cc43e34f131cc9a315ef0337e
+
+Fixes: 21677cfc562a ("V4L/DVB: ir-core: add imon driver")
+Reported-by: syzbot+0c3cb6dc05fbbdc3ad66@syzkaller.appspotmail.com
+Signed-off-by: Gautam Menghani <gautammenghani201@gmail.com>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/rc/imon.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
+index bc9ac6002e25..98a38755c694 100644
+--- a/drivers/media/rc/imon.c
++++ b/drivers/media/rc/imon.c
+@@ -646,15 +646,14 @@ static int send_packet(struct imon_context *ictx)
+               pr_err_ratelimited("error submitting urb(%d)\n", retval);
+       } else {
+               /* Wait for transmission to complete (or abort) */
+-              mutex_unlock(&ictx->lock);
+               retval = wait_for_completion_interruptible(
+                               &ictx->tx.finished);
+               if (retval) {
+                       usb_kill_urb(ictx->tx_urb);
+                       pr_err_ratelimited("task interrupted\n");
+               }
+-              mutex_lock(&ictx->lock);
++              ictx->tx.busy = false;
+               retval = ictx->tx.status;
+               if (retval)
+                       pr_err_ratelimited("packet tx failed (%d)\n", retval);
+@@ -958,7 +957,8 @@ static ssize_t vfd_write(struct file *file, const char __user *buf,
+       if (ictx->disconnected)
+               return -ENODEV;
+-      mutex_lock(&ictx->lock);
++      if (mutex_lock_interruptible(&ictx->lock))
++              return -ERESTARTSYS;
+       if (!ictx->dev_present_intf0) {
+               pr_err_ratelimited("no iMON device present\n");
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-platform-exynos4-is-fix-error-handling-in-fimc.patch b/queue-5.10/media-platform-exynos4-is-fix-error-handling-in-fimc.patch
new file mode 100644 (file)
index 0000000..572c2c0
--- /dev/null
@@ -0,0 +1,75 @@
+From e702ac0e4f8c5df01a2753e2a691ca90b0a7d1b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 06:08:53 +0000
+Subject: media: platform: exynos4-is: Fix error handling in fimc_md_init()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit b434422c45282a0573d8123239abc41fa72665d4 ]
+
+A problem about modprobe s5p_fimc failed is triggered with the
+following log given:
+
+ [  272.075275] Error: Driver 'exynos4-fimc' is already registered, aborting...
+ modprobe: ERROR: could not insert 's5p_fimc': Device or resource busy
+
+The reason is that fimc_md_init() returns platform_driver_register()
+directly without checking its return value, if platform_driver_register()
+failed, it returns without unregister fimc_driver, resulting the
+s5p_fimc can never be installed later.
+A simple call graph is shown as below:
+
+ fimc_md_init()
+   fimc_register_driver() # register fimc_driver
+   platform_driver_register()
+     platform_driver_register()
+       driver_register()
+         bus_add_driver()
+           dev = kzalloc(...) # OOM happened
+   # return without unregister fimc_driver
+
+Fix by unregister fimc_driver when platform_driver_register() returns
+error.
+
+Fixes: d3953223b090 ("[media] s5p-fimc: Add the media device driver")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/exynos4-is/fimc-core.c | 2 +-
+ drivers/media/platform/exynos4-is/media-dev.c | 6 +++++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
+index 08d1f39a914c..60b28e6f739e 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.c
++++ b/drivers/media/platform/exynos4-is/fimc-core.c
+@@ -1174,7 +1174,7 @@ int __init fimc_register_driver(void)
+       return platform_driver_register(&fimc_driver);
+ }
+-void __exit fimc_unregister_driver(void)
++void fimc_unregister_driver(void)
+ {
+       platform_driver_unregister(&fimc_driver);
+ }
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index a9ab2a28fc26..bd37011fb671 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1582,7 +1582,11 @@ static int __init fimc_md_init(void)
+       if (ret)
+               return ret;
+-      return platform_driver_register(&fimc_md_driver);
++      ret = platform_driver_register(&fimc_md_driver);
++      if (ret)
++              fimc_unregister_driver();
++
++      return ret;
+ }
+ static void __exit fimc_md_exit(void)
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-platform-exynos4-is-fix-return-value-check-in-.patch b/queue-5.10/media-platform-exynos4-is-fix-return-value-check-in-.patch
new file mode 100644 (file)
index 0000000..c161a52
--- /dev/null
@@ -0,0 +1,37 @@
+From 653ad97701bc849f5d2881a6fbddf242dad00c5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Oct 2022 21:46:50 +0800
+Subject: media: platform: exynos4-is: fix return value check in
+ fimc_md_probe()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit e38e42c078da4af962d322b97e726dcb2f184e3f ]
+
+devm_pinctrl_get() may return ERR_PTR(-EPROBE_DEFER), add a minus sign
+to fix it.
+
+Fixes: 4163851f7b99 ("[media] s5p-fimc: Use pinctrl API for camera ports configuration")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 8603c578f55f..a9ab2a28fc26 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1470,7 +1470,7 @@ static int fimc_md_probe(struct platform_device *pdev)
+       pinctrl = devm_pinctrl_get(dev);
+       if (IS_ERR(pinctrl)) {
+               ret = PTR_ERR(pinctrl);
+-              if (ret != EPROBE_DEFER)
++              if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get pinctrl: %d\n", ret);
+               goto err_clk;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-s5p-mfc-add-variant-data-for-mfc-v7-hardware-f.patch b/queue-5.10/media-s5p-mfc-add-variant-data-for-mfc-v7-hardware-f.patch
new file mode 100644 (file)
index 0000000..70b983d
--- /dev/null
@@ -0,0 +1,66 @@
+From 7512a4c47a38e6ab11b1aaa0d024950a80979a50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 11:50:23 +0000
+Subject: media: s5p-mfc: Add variant data for MFC v7 hardware for Exynos 3250
+ SoC
+
+From: Aakarsh Jain <aakarsh.jain@samsung.com>
+
+[ Upstream commit f50ebe10f5d8092c37e2bd430c78e03bf38b1e20 ]
+
+Commit 5441e9dafdfc6dc40 ("[media] s5p-mfc: Core support for MFC v7")
+which adds mfc v7 support for Exynos3250 and use the same compatible
+string as used by Exynos5240 but both the IPs are a bit different in
+terms of IP clock.
+Add variant driver data based on the new compatible string
+"samsung,exynos3250-mfc" for Exynos3250 SoC.
+
+Suggested-by: Alim Akhtar <alim.akhtar@samsung.com>
+Fixes: 5441e9dafdfc ("[media] s5p-mfc: Core support for MFC v7")
+Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
+Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/s5p-mfc/s5p_mfc.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
+index f336a9543273..6cbec3bbfce6 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
+@@ -1584,8 +1584,18 @@ static struct s5p_mfc_variant mfc_drvdata_v7 = {
+       .port_num       = MFC_NUM_PORTS_V7,
+       .buf_size       = &buf_size_v7,
+       .fw_name[0]     = "s5p-mfc-v7.fw",
+-      .clk_names      = {"mfc", "sclk_mfc"},
+-      .num_clocks     = 2,
++      .clk_names      = {"mfc"},
++      .num_clocks     = 1,
++};
++
++static struct s5p_mfc_variant mfc_drvdata_v7_3250 = {
++      .version        = MFC_VERSION_V7,
++      .version_bit    = MFC_V7_BIT,
++      .port_num       = MFC_NUM_PORTS_V7,
++      .buf_size       = &buf_size_v7,
++      .fw_name[0]     = "s5p-mfc-v7.fw",
++      .clk_names      = {"mfc", "sclk_mfc"},
++      .num_clocks     = 2,
+ };
+ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = {
+@@ -1655,6 +1665,9 @@ static const struct of_device_id exynos_mfc_match[] = {
+       }, {
+               .compatible = "samsung,mfc-v7",
+               .data = &mfc_drvdata_v7,
++      }, {
++              .compatible = "samsung,exynos3250-mfc",
++              .data = &mfc_drvdata_v7_3250,
+       }, {
+               .compatible = "samsung,mfc-v8",
+               .data = &mfc_drvdata_v8,
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-saa7164-fix-missing-pci_disable_device.patch b/queue-5.10/media-saa7164-fix-missing-pci_disable_device.patch
new file mode 100644 (file)
index 0000000..e7f37eb
--- /dev/null
@@ -0,0 +1,45 @@
+From 8b6f3f0eff4091758ebee62470d5090bc38d16d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Nov 2022 11:31:26 +0000
+Subject: media: saa7164: fix missing pci_disable_device()
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+[ Upstream commit 57fb35d7542384cac8f198cd1c927540ad38b61a ]
+
+Add missing pci_disable_device() in the error path in saa7164_initdev().
+
+Fixes: 443c1228d505 ("V4L/DVB (12923): SAA7164: Add support for the NXP SAA7164 silicon")
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/saa7164/saa7164-core.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
+index 6c08b77bfd47..3cadfbe60fe6 100644
+--- a/drivers/media/pci/saa7164/saa7164-core.c
++++ b/drivers/media/pci/saa7164/saa7164-core.c
+@@ -1270,7 +1270,7 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
+       if (saa7164_dev_setup(dev) < 0) {
+               err = -EINVAL;
+-              goto fail_free;
++              goto fail_dev;
+       }
+       /* print pci info */
+@@ -1438,6 +1438,8 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
+ fail_irq:
+       saa7164_dev_unregister(dev);
++fail_dev:
++      pci_disable_device(pci_dev);
+ fail_free:
+       v4l2_device_unregister(&dev->v4l2_dev);
+       kfree(dev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-si470x-fix-use-after-free-in-si470x_int_in_cal.patch b/queue-5.10/media-si470x-fix-use-after-free-in-si470x_int_in_cal.patch
new file mode 100644 (file)
index 0000000..86111a1
--- /dev/null
@@ -0,0 +1,64 @@
+From d7ed80959ad56f506bce1a3ba6abb482c4156912 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 03:51:59 +0900
+Subject: media: si470x: Fix use-after-free in si470x_int_in_callback()
+
+From: Shigeru Yoshida <syoshida@redhat.com>
+
+[ Upstream commit 7d21e0b1b41b21d628bf2afce777727bd4479aa5 ]
+
+syzbot reported use-after-free in si470x_int_in_callback() [1].  This
+indicates that urb->context, which contains struct si470x_device
+object, is freed when si470x_int_in_callback() is called.
+
+The cause of this issue is that si470x_int_in_callback() is called for
+freed urb.
+
+si470x_usb_driver_probe() calls si470x_start_usb(), which then calls
+usb_submit_urb() and si470x_start().  If si470x_start_usb() fails,
+si470x_usb_driver_probe() doesn't kill urb, but it just frees struct
+si470x_device object, as depicted below:
+
+si470x_usb_driver_probe()
+  ...
+  si470x_start_usb()
+    ...
+    usb_submit_urb()
+    retval = si470x_start()
+    return retval
+  if (retval < 0)
+    free struct si470x_device object, but don't kill urb
+
+This patch fixes this issue by killing urb when si470x_start_usb()
+fails and urb is submitted.  If si470x_start_usb() fails and urb is
+not submitted, i.e. submitting usb fails, it just frees struct
+si470x_device object.
+
+Reported-by: syzbot+9ca7a12fd736d93e0232@syzkaller.appspotmail.com
+Link: https://syzkaller.appspot.com/bug?id=94ed6dddd5a55e90fd4bab942aa4bb297741d977 [1]
+Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/radio/si470x/radio-si470x-usb.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
+index 3f8634a46573..1365ae732b79 100644
+--- a/drivers/media/radio/si470x/radio-si470x-usb.c
++++ b/drivers/media/radio/si470x/radio-si470x-usb.c
+@@ -733,8 +733,10 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
+       /* start radio */
+       retval = si470x_start_usb(radio);
+-      if (retval < 0)
++      if (retval < 0 && !radio->int_in_running)
+               goto err_buf;
++      else if (retval < 0)    /* in case of radio->int_in_running == 1 */
++              goto err_all;
+       /* set initial frequency */
+       si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-solo6x10-fix-possible-memory-leak-in-solo_sysf.patch b/queue-5.10/media-solo6x10-fix-possible-memory-leak-in-solo_sysf.patch
new file mode 100644 (file)
index 0000000..749d5d1
--- /dev/null
@@ -0,0 +1,38 @@
+From bd8972dc29b68bd0ed8d681e61d20e7a8f1740c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 16:24:23 +0800
+Subject: media: solo6x10: fix possible memory leak in solo_sysfs_init()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 7f5866dd96d95b74e439f6ee17b8abd8195179fb ]
+
+If device_register() returns error in solo_sysfs_init(), the
+name allocated by dev_set_name() need be freed. As comment of
+device_register() says, it should use put_device() to give up
+the reference in the error path. So fix this by calling
+put_device(), then the name can be freed in kobject_cleanup().
+
+Fixes: dcae5dacbce5 ("[media] solo6x10: sync to latest code from Bluecherry's git repo")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/solo6x10/solo6x10-core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/pci/solo6x10/solo6x10-core.c b/drivers/media/pci/solo6x10/solo6x10-core.c
+index d497afc7e7b7..4ebb1e020fad 100644
+--- a/drivers/media/pci/solo6x10/solo6x10-core.c
++++ b/drivers/media/pci/solo6x10/solo6x10-core.c
+@@ -420,6 +420,7 @@ static int solo_sysfs_init(struct solo_dev *solo_dev)
+                    solo_dev->nr_chans);
+       if (device_register(dev)) {
++              put_device(dev);
+               dev->parent = NULL;
+               return -ENOMEM;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-videobuf-dma-contig-use-dma_mmap_coherent.patch b/queue-5.10/media-videobuf-dma-contig-use-dma_mmap_coherent.patch
new file mode 100644 (file)
index 0000000..6db99a1
--- /dev/null
@@ -0,0 +1,87 @@
+From e39def8b3dde59b1b28e2c0b202ed0e98332f854 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Dec 2019 11:39:07 +0100
+Subject: media: videobuf-dma-contig: use dma_mmap_coherent
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit b3dc3f8e49577840dc8ac8a365c5b3da4edb10b8 ]
+
+dma_alloc_coherent does not return a physical address, but a DMA address,
+which might be remapped or have an offset.  Passing the DMA address to
+vm_iomap_memory is thus broken.
+
+Use the proper dma_mmap_coherent helper instead, and stop passing
+__GFP_COMP to dma_alloc_coherent, as the memory management inside the
+DMA allocator is hidden from the callers and does not require it.
+
+With this the gfp_t argument to __videobuf_dc_alloc can be removed and
+hard coded to GFP_KERNEL.
+
+Fixes: a8f3c203e19b ("[media] videobuf-dma-contig: add cache support")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/v4l2-core/videobuf-dma-contig.c | 22 +++++++------------
+ 1 file changed, 8 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c
+index 52312ce2ba05..f2c439359557 100644
+--- a/drivers/media/v4l2-core/videobuf-dma-contig.c
++++ b/drivers/media/v4l2-core/videobuf-dma-contig.c
+@@ -36,12 +36,11 @@ struct videobuf_dma_contig_memory {
+ static int __videobuf_dc_alloc(struct device *dev,
+                              struct videobuf_dma_contig_memory *mem,
+-                             unsigned long size, gfp_t flags)
++                             unsigned long size)
+ {
+       mem->size = size;
+-      mem->vaddr = dma_alloc_coherent(dev, mem->size,
+-                                      &mem->dma_handle, flags);
+-
++      mem->vaddr = dma_alloc_coherent(dev, mem->size, &mem->dma_handle,
++                                      GFP_KERNEL);
+       if (!mem->vaddr) {
+               dev_err(dev, "memory alloc size %ld failed\n", mem->size);
+               return -ENOMEM;
+@@ -258,8 +257,7 @@ static int __videobuf_iolock(struct videobuf_queue *q,
+                       return videobuf_dma_contig_user_get(mem, vb);
+               /* allocate memory for the read() method */
+-              if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size),
+-                                      GFP_KERNEL))
++              if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size)))
+                       return -ENOMEM;
+               break;
+       case V4L2_MEMORY_OVERLAY:
+@@ -295,22 +293,18 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
+       BUG_ON(!mem);
+       MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+-      if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize),
+-                              GFP_KERNEL | __GFP_COMP))
++      if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize)))
+               goto error;
+-      /* Try to remap memory */
+-      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+-
+       /* the "vm_pgoff" is just used in v4l2 to find the
+        * corresponding buffer data structure which is allocated
+        * earlier and it does not mean the offset from the physical
+        * buffer start address as usual. So set it to 0 to pass
+-       * the sanity check in vm_iomap_memory().
++       * the sanity check in dma_mmap_coherent().
+        */
+       vma->vm_pgoff = 0;
+-
+-      retval = vm_iomap_memory(vma, mem->dma_handle, mem->size);
++      retval = dma_mmap_coherent(q->dev, vma, mem->vaddr, mem->dma_handle,
++                                 mem->size);
+       if (retval) {
+               dev_err(q->dev, "mmap: remap failed with error %d. ",
+                       retval);
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-vidtv-fix-use-after-free-in-vidtv_bridge_dvb_i.patch b/queue-5.10/media-vidtv-fix-use-after-free-in-vidtv_bridge_dvb_i.patch
new file mode 100644 (file)
index 0000000..7927f04
--- /dev/null
@@ -0,0 +1,91 @@
+From f00210d2f95964c7dee55ea7c9a615b852160290 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 15:06:30 +0800
+Subject: media: vidtv: Fix use-after-free in vidtv_bridge_dvb_init()
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit ba8d9405935097e296bcf7a942c3a01df0edb865 ]
+
+KASAN reports a use-after-free:
+BUG: KASAN: use-after-free in dvb_dmxdev_release+0x4d5/0x5d0 [dvb_core]
+Call Trace:
+ ...
+ dvb_dmxdev_release+0x4d5/0x5d0 [dvb_core]
+ vidtv_bridge_probe+0x7bf/0xa40 [dvb_vidtv_bridge]
+ platform_probe+0xb6/0x170
+ ...
+Allocated by task 1238:
+ ...
+ dvb_register_device+0x1a7/0xa70 [dvb_core]
+ dvb_dmxdev_init+0x2af/0x4a0 [dvb_core]
+ vidtv_bridge_probe+0x766/0xa40 [dvb_vidtv_bridge]
+ ...
+Freed by task 1238:
+ dvb_register_device+0x6d2/0xa70 [dvb_core]
+ dvb_dmxdev_init+0x2af/0x4a0 [dvb_core]
+ vidtv_bridge_probe+0x766/0xa40 [dvb_vidtv_bridge]
+ ...
+
+It is because the error handling in vidtv_bridge_dvb_init() is wrong.
+
+First, vidtv_bridge_dmx(dev)_init() will clean themselves when fail, but
+goto fail_dmx(_dev): calls release functions again, which causes
+use-after-free.
+
+Also, in fail_fe, fail_tuner_probe and fail_demod_probe, j = i will cause
+out-of-bound when i finished its loop (i == NUM_FE). And the loop
+releasing is wrong, although now NUM_FE is 1 so it won't cause problem.
+
+Fix this by correctly releasing everything.
+
+Fixes: f90cf6079bf6 ("media: vidtv: add a bridge driver")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/test-drivers/vidtv/vidtv_bridge.c   | 22 +++++++------------
+ 1 file changed, 8 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+index fc64d0c8492a..3c281265a9ec 100644
+--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c
++++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+@@ -456,26 +456,20 @@ static int vidtv_bridge_dvb_init(struct vidtv_dvb *dvb)
+       for (j = j - 1; j >= 0; --j)
+               dvb->demux.dmx.remove_frontend(&dvb->demux.dmx,
+                                              &dvb->dmx_fe[j]);
+-fail_dmx_dev:
+       dvb_dmxdev_release(&dvb->dmx_dev);
+-fail_dmx:
++fail_dmx_dev:
+       dvb_dmx_release(&dvb->demux);
++fail_dmx:
++fail_demod_probe:
++      for (i = i - 1; i >= 0; --i) {
++              dvb_unregister_frontend(dvb->fe[i]);
+ fail_fe:
+-      for (j = i; j >= 0; --j)
+-              dvb_unregister_frontend(dvb->fe[j]);
++              dvb_module_release(dvb->i2c_client_tuner[i]);
+ fail_tuner_probe:
+-      for (j = i; j >= 0; --j)
+-              if (dvb->i2c_client_tuner[j])
+-                      dvb_module_release(dvb->i2c_client_tuner[j]);
+-
+-fail_demod_probe:
+-      for (j = i; j >= 0; --j)
+-              if (dvb->i2c_client_demod[j])
+-                      dvb_module_release(dvb->i2c_client_demod[j]);
+-
++              dvb_module_release(dvb->i2c_client_demod[i]);
++      }
+ fail_adapter:
+       dvb_unregister_adapter(&dvb->adapter);
+-
+ fail_i2c:
+       i2c_del_adapter(&dvb->i2c_adapter);
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-vimc-fix-wrong-function-called-when-vimc_init-.patch b/queue-5.10/media-vimc-fix-wrong-function-called-when-vimc_init-.patch
new file mode 100644 (file)
index 0000000..5be95c6
--- /dev/null
@@ -0,0 +1,48 @@
+From 702687a02483ca5de7cfd12ba6b6df175fc63285 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 07:26:33 +0000
+Subject: media: vimc: Fix wrong function called when vimc_init() fails
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit f74d3f326d1d5b8951ce263c59a121ecfa65e7c0 ]
+
+In vimc_init(), when platform_driver_register(&vimc_pdrv) fails,
+platform_driver_unregister(&vimc_pdrv) is wrongly called rather than
+platform_device_unregister(&vimc_pdev), which causes kernel warning:
+
+ Unexpected driver unregister!
+ WARNING: CPU: 1 PID: 14517 at drivers/base/driver.c:270 driver_unregister+0x8f/0xb0
+ RIP: 0010:driver_unregister+0x8f/0xb0
+ Call Trace:
+  <TASK>
+  vimc_init+0x7d/0x1000 [vimc]
+  do_one_initcall+0xd0/0x4e0
+  do_init_module+0x1cf/0x6b0
+  load_module+0x65c2/0x7820
+
+Fixes: 4a29b7090749 ("[media] vimc: Subdevices as modules")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/test-drivers/vimc/vimc-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/test-drivers/vimc/vimc-core.c b/drivers/media/test-drivers/vimc/vimc-core.c
+index 4b0ae6f51d76..857529ce3638 100644
+--- a/drivers/media/test-drivers/vimc/vimc-core.c
++++ b/drivers/media/test-drivers/vimc/vimc-core.c
+@@ -357,7 +357,7 @@ static int __init vimc_init(void)
+       if (ret) {
+               dev_err(&vimc_pdev.dev,
+                       "platform driver registration failed (err=%d)\n", ret);
+-              platform_driver_unregister(&vimc_pdrv);
++              platform_device_unregister(&vimc_pdev);
+               return ret;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/media-vivid-fix-compose-size-exceed-boundary.patch b/queue-5.10/media-vivid-fix-compose-size-exceed-boundary.patch
new file mode 100644 (file)
index 0000000..5136bd1
--- /dev/null
@@ -0,0 +1,57 @@
+From f61fc71b870cac0b2c5299e9ab67334f880915f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 20:38:55 +0800
+Subject: media: vivid: fix compose size exceed boundary
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+[ Upstream commit 94a7ad9283464b75b12516c5512541d467cefcf8 ]
+
+syzkaller found a bug:
+
+ BUG: unable to handle page fault for address: ffffc9000a3b1000
+ #PF: supervisor write access in kernel mode
+ #PF: error_code(0x0002) - not-present page
+ PGD 100000067 P4D 100000067 PUD 10015f067 PMD 1121ca067 PTE 0
+ Oops: 0002 [#1] PREEMPT SMP
+ CPU: 0 PID: 23489 Comm: vivid-000-vid-c Not tainted 6.1.0-rc1+ #512
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
+ RIP: 0010:memcpy_erms+0x6/0x10
+[...]
+ Call Trace:
+  <TASK>
+  ? tpg_fill_plane_buffer+0x856/0x15b0
+  vivid_fillbuff+0x8ac/0x1110
+  vivid_thread_vid_cap_tick+0x361/0xc90
+  vivid_thread_vid_cap+0x21a/0x3a0
+  kthread+0x143/0x180
+  ret_from_fork+0x1f/0x30
+  </TASK>
+
+This is because we forget to check boundary after adjust compose->height
+int V4L2_SEL_TGT_CROP case. Add v4l2_rect_map_inside() to fix this problem
+for this case.
+
+Fixes: ef834f7836ec ("[media] vivid: add the video capture and output parts")
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/test-drivers/vivid/vivid-vid-cap.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+index d493bd17481b..437889e51ca0 100644
+--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
++++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+@@ -961,6 +961,7 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
+                       if (dev->has_compose_cap) {
+                               v4l2_rect_set_min_size(compose, &min_rect);
+                               v4l2_rect_set_max_size(compose, &max_rect);
++                              v4l2_rect_map_inside(compose, &fmt);
+                       }
+                       dev->fmt_cap_rect = fmt;
+                       tpg_s_buf_height(&dev->tpg, fmt.height);
+-- 
+2.35.1
+
diff --git a/queue-5.10/mfd-qcom_rpm-fix-an-error-handling-path-in-qcom_rpm_.patch b/queue-5.10/mfd-qcom_rpm-fix-an-error-handling-path-in-qcom_rpm_.patch
new file mode 100644 (file)
index 0000000..d330cb9
--- /dev/null
@@ -0,0 +1,55 @@
+From 2aef24dc72fb3711cabe064ee40403e7b69d3383 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Nov 2022 18:19:01 +0100
+Subject: mfd: qcom_rpm: Fix an error handling path in qcom_rpm_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 36579aca877a62f67ecd77eb3edefc4c86292406 ]
+
+If an error occurs after the clk_prepare_enable() call, a corresponding
+clk_disable_unprepare() should be called.
+
+Simplify code and switch to devm_clk_get_enabled() to fix it.
+
+Fixes: 3526403353c2 ("mfd: qcom_rpm: Handle message RAM clock")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://lore.kernel.org/r/e39752476d02605b2be46cab7115f71255ce13a8.1668949256.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/qcom_rpm.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c
+index 71bc34b74bc9..ea5eb94427c4 100644
+--- a/drivers/mfd/qcom_rpm.c
++++ b/drivers/mfd/qcom_rpm.c
+@@ -547,7 +547,7 @@ static int qcom_rpm_probe(struct platform_device *pdev)
+       init_completion(&rpm->ack);
+       /* Enable message RAM clock */
+-      rpm->ramclk = devm_clk_get(&pdev->dev, "ram");
++      rpm->ramclk = devm_clk_get_enabled(&pdev->dev, "ram");
+       if (IS_ERR(rpm->ramclk)) {
+               ret = PTR_ERR(rpm->ramclk);
+               if (ret == -EPROBE_DEFER)
+@@ -558,7 +558,6 @@ static int qcom_rpm_probe(struct platform_device *pdev)
+                */
+               rpm->ramclk = NULL;
+       }
+-      clk_prepare_enable(rpm->ramclk); /* Accepts NULL */
+       irq_ack = platform_get_irq_byname(pdev, "ack");
+       if (irq_ack < 0)
+@@ -681,7 +680,6 @@ static int qcom_rpm_remove(struct platform_device *pdev)
+       struct qcom_rpm *rpm = dev_get_drvdata(&pdev->dev);
+       of_platform_depopulate(&pdev->dev);
+-      clk_disable_unprepare(rpm->ramclk);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/mips-bcm63xx-add-check-for-null-for-clk-in-clk_enabl.patch b/queue-5.10/mips-bcm63xx-add-check-for-null-for-clk-in-clk_enabl.patch
new file mode 100644 (file)
index 0000000..1547ea9
--- /dev/null
@@ -0,0 +1,44 @@
+From 652bb55ee6a46dac377d4d2bc86ab1a395639356 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 13:05:50 +0300
+Subject: MIPS: BCM63xx: Add check for NULL for clk in clk_enable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Anastasia Belova <abelova@astralinux.ru>
+
+[ Upstream commit ee9ef11bd2a59c2fefaa0959e5efcdf040d7c654 ]
+
+Check clk for NULL before calling clk_enable_unlocked where clk
+is dereferenced. There is such check in other implementations
+of clk_enable.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: e7300d04bd08 ("MIPS: BCM63xx: Add support for the Broadcom BCM63xx family of SOCs.")
+Signed-off-by: Anastasia Belova <abelova@astralinux.ru>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/bcm63xx/clk.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
+index dcfa0ea912fe..f183c45503ce 100644
+--- a/arch/mips/bcm63xx/clk.c
++++ b/arch/mips/bcm63xx/clk.c
+@@ -361,6 +361,8 @@ static struct clk clk_periph = {
+  */
+ int clk_enable(struct clk *clk)
+ {
++      if (!clk)
++              return 0;
+       mutex_lock(&clocks_mutex);
+       clk_enable_unlocked(clk);
+       mutex_unlock(&clocks_mutex);
+-- 
+2.35.1
+
diff --git a/queue-5.10/mips-octeon-warn-only-once-if-deprecated-link-status.patch b/queue-5.10/mips-octeon-warn-only-once-if-deprecated-link-status.patch
new file mode 100644 (file)
index 0000000..ea94b98
--- /dev/null
@@ -0,0 +1,53 @@
+From c0db54d53cb02ac3255afc511f7ab20dcbbc7d42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 12:25:57 +0100
+Subject: MIPS: OCTEON: warn only once if deprecated link status is being used
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ladislav Michl <ladis@linux-mips.org>
+
+[ Upstream commit 4c587a982603d7e7e751b4925809a1512099a690 ]
+
+Avoid flooding kernel log with warnings.
+
+Fixes: 2c0756d306c2 ("MIPS: OCTEON: warn if deprecated link status is being used")
+Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/cavium-octeon/executive/cvmx-helper-board.c | 2 +-
+ arch/mips/cavium-octeon/executive/cvmx-helper.c       | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+index abd11b7af22f..9b791ccf874f 100644
+--- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
++++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+@@ -211,7 +211,7 @@ union cvmx_helper_link_info __cvmx_helper_board_link_get(int ipd_port)
+ {
+       union cvmx_helper_link_info result;
+-      WARN(!octeon_is_simulation(),
++      WARN_ONCE(!octeon_is_simulation(),
+            "Using deprecated link status - please update your DT");
+       /* Unless we fix it later, all links are defaulted to down */
+diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c
+index 6044ff471002..a18ad2daf005 100644
+--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c
++++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
+@@ -1100,7 +1100,7 @@ union cvmx_helper_link_info cvmx_helper_link_get(int ipd_port)
+               if (index == 0)
+                       result = __cvmx_helper_rgmii_link_get(ipd_port);
+               else {
+-                      WARN(1, "Using deprecated link status - please update your DT");
++                      WARN_ONCE(1, "Using deprecated link status - please update your DT");
+                       result.s.full_duplex = 1;
+                       result.s.link_up = 1;
+                       result.s.speed = 1000;
+-- 
+2.35.1
+
diff --git a/queue-5.10/mips-vpe-cmp-fix-possible-memory-leak-while-module-e.patch b/queue-5.10/mips-vpe-cmp-fix-possible-memory-leak-while-module-e.patch
new file mode 100644 (file)
index 0000000..ac53579
--- /dev/null
@@ -0,0 +1,55 @@
+From 8498157c90fe6d418cfca0ba274ede050e9b2d14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 11:39:45 +0800
+Subject: MIPS: vpe-cmp: fix possible memory leak while module exiting
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit c5ed1fe0801f0c66b0fbce2785239a5664629057 ]
+
+dev_set_name() allocates memory for name, it need be freed
+when module exiting, call put_device() to give up reference,
+so that it can be freed in kobject_cleanup() when the refcount
+hit to 0. The vpe_device is static, so remove kfree() from
+vpe_device_release().
+
+Fixes: 17a1d523aa58 ("MIPS: APRP: Add VPE loader support for CMP platforms.")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/kernel/vpe-cmp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/mips/kernel/vpe-cmp.c b/arch/mips/kernel/vpe-cmp.c
+index 9268ebc0f61e..903c07bdc92d 100644
+--- a/arch/mips/kernel/vpe-cmp.c
++++ b/arch/mips/kernel/vpe-cmp.c
+@@ -75,7 +75,6 @@ ATTRIBUTE_GROUPS(vpe);
+ static void vpe_device_release(struct device *cd)
+ {
+-      kfree(cd);
+ }
+ static struct class vpe_class = {
+@@ -157,6 +156,7 @@ int __init vpe_module_init(void)
+       device_del(&vpe_device);
+ out_class:
++      put_device(&vpe_device);
+       class_unregister(&vpe_class);
+ out_chrdev:
+@@ -169,7 +169,7 @@ void __exit vpe_module_exit(void)
+ {
+       struct vpe *v, *n;
+-      device_del(&vpe_device);
++      device_unregister(&vpe_device);
+       class_unregister(&vpe_class);
+       unregister_chrdev(major, VPE_MODULE_NAME);
+-- 
+2.35.1
+
diff --git a/queue-5.10/mips-vpe-mt-fix-possible-memory-leak-while-module-ex.patch b/queue-5.10/mips-vpe-mt-fix-possible-memory-leak-while-module-ex.patch
new file mode 100644 (file)
index 0000000..4528106
--- /dev/null
@@ -0,0 +1,56 @@
+From 54e285c48f2204be521e76bca6b4d3779c601568 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 11:39:44 +0800
+Subject: MIPS: vpe-mt: fix possible memory leak while module exiting
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 5822e8cc84ee37338ab0bdc3124f6eec04dc232d ]
+
+Afer commit 1fa5ae857bb1 ("driver core: get rid of struct device's
+bus_id string array"), the name of device is allocated dynamically,
+it need be freed when module exiting, call put_device() to give up
+reference, so that it can be freed in kobject_cleanup() when the
+refcount hit to 0. The vpe_device is static, so remove kfree() from
+vpe_device_release().
+
+Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/kernel/vpe-mt.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/mips/kernel/vpe-mt.c b/arch/mips/kernel/vpe-mt.c
+index 2e003b11a098..9fd7cd48ea1d 100644
+--- a/arch/mips/kernel/vpe-mt.c
++++ b/arch/mips/kernel/vpe-mt.c
+@@ -313,7 +313,6 @@ ATTRIBUTE_GROUPS(vpe);
+ static void vpe_device_release(struct device *cd)
+ {
+-      kfree(cd);
+ }
+ static struct class vpe_class = {
+@@ -497,6 +496,7 @@ int __init vpe_module_init(void)
+       device_del(&vpe_device);
+ out_class:
++      put_device(&vpe_device);
+       class_unregister(&vpe_class);
+ out_chrdev:
+@@ -509,7 +509,7 @@ void __exit vpe_module_exit(void)
+ {
+       struct vpe *v, *n;
+-      device_del(&vpe_device);
++      device_unregister(&vpe_device);
+       class_unregister(&vpe_class);
+       unregister_chrdev(major, VPE_MODULE_NAME);
+-- 
+2.35.1
+
diff --git a/queue-5.10/misc-ocxl-fix-possible-name-leak-in-ocxl_file_regist.patch b/queue-5.10/misc-ocxl-fix-possible-name-leak-in-ocxl_file_regist.patch
new file mode 100644 (file)
index 0000000..0c41e4a
--- /dev/null
@@ -0,0 +1,48 @@
+From 9d171ef34cdecd4f7c18b3b6e8a19ff2b7d0f29c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 22:59:29 +0800
+Subject: misc: ocxl: fix possible name leak in ocxl_file_register_afu()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit a4cb1004aeed2ab893a058fad00a5b41a12c4691 ]
+
+If device_register() returns error in ocxl_file_register_afu(),
+the name allocated by dev_set_name() need be freed. As comment
+of device_register() says, it should use put_device() to give
+up the reference in the error path. So fix this by calling
+put_device(), then the name can be freed in kobject_cleanup(),
+and info is freed in info_release().
+
+Fixes: 75ca758adbaf ("ocxl: Create a clear delineation between ocxl backend & frontend")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: Andrew Donnellan <ajd@linux.ibm.com>
+Acked-by: Frederic Barrat <fbarrat@linux.ibm.com>
+Link: https://lore.kernel.org/r/20221111145929.2429271-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/ocxl/file.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c
+index e094809b54ff..524ded87964d 100644
+--- a/drivers/misc/ocxl/file.c
++++ b/drivers/misc/ocxl/file.c
+@@ -543,8 +543,11 @@ int ocxl_file_register_afu(struct ocxl_afu *afu)
+               goto err_put;
+       rc = device_register(&info->dev);
+-      if (rc)
+-              goto err_put;
++      if (rc) {
++              free_minor(info);
++              put_device(&info->dev);
++              return rc;
++      }
+       rc = ocxl_sysfs_register_afu(info);
+       if (rc)
+-- 
+2.35.1
+
diff --git a/queue-5.10/misc-sgi-gru-fix-use-after-free-error-in-gru_set_con.patch b/queue-5.10/misc-sgi-gru-fix-use-after-free-error-in-gru_set_con.patch
new file mode 100644 (file)
index 0000000..ec56511
--- /dev/null
@@ -0,0 +1,140 @@
+From 2cac92e5294cf166db191a2057e1d9f5885b7fde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 11:50:33 +0800
+Subject: misc: sgi-gru: fix use-after-free error in gru_set_context_option,
+ gru_fault and gru_handle_user_call_os
+
+From: Zheng Wang <zyytlz.wz@163.com>
+
+[ Upstream commit 643a16a0eb1d6ac23744bb6e90a00fc21148a9dc ]
+
+In some bad situation, the gts may be freed gru_check_chiplet_assignment.
+The call chain can be gru_unload_context->gru_free_gru_context->gts_drop
+and kfree finally. However, the caller didn't know if the gts is freed
+or not and use it afterwards. This will trigger a Use after Free bug.
+
+Fix it by introducing a return value to see if it's in error path or not.
+Free the gts in caller if gru_check_chiplet_assignment check failed.
+
+Fixes: 55484c45dbec ("gru: allow users to specify gru chiplet 2")
+Signed-off-by: Zheng Wang <zyytlz.wz@163.com>
+Acked-by: Dimitri Sivanich <sivanich@hpe.com>
+Link: https://lore.kernel.org/r/20221110035033.19498-1-zyytlz.wz@163.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/sgi-gru/grufault.c  | 13 +++++++++++--
+ drivers/misc/sgi-gru/grumain.c   | 22 ++++++++++++++++++----
+ drivers/misc/sgi-gru/grutables.h |  2 +-
+ 3 files changed, 30 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
+index 723825524ea0..9c7d475d1890 100644
+--- a/drivers/misc/sgi-gru/grufault.c
++++ b/drivers/misc/sgi-gru/grufault.c
+@@ -648,6 +648,7 @@ int gru_handle_user_call_os(unsigned long cb)
+       if ((cb & (GRU_HANDLE_STRIDE - 1)) || ucbnum >= GRU_NUM_CB)
+               return -EINVAL;
++again:
+       gts = gru_find_lock_gts(cb);
+       if (!gts)
+               return -EINVAL;
+@@ -656,7 +657,11 @@ int gru_handle_user_call_os(unsigned long cb)
+       if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
+               goto exit;
+-      gru_check_context_placement(gts);
++      if (gru_check_context_placement(gts)) {
++              gru_unlock_gts(gts);
++              gru_unload_context(gts, 1);
++              goto again;
++      }
+       /*
+        * CCH may contain stale data if ts_force_cch_reload is set.
+@@ -874,7 +879,11 @@ int gru_set_context_option(unsigned long arg)
+               } else {
+                       gts->ts_user_blade_id = req.val1;
+                       gts->ts_user_chiplet_id = req.val0;
+-                      gru_check_context_placement(gts);
++                      if (gru_check_context_placement(gts)) {
++                              gru_unlock_gts(gts);
++                              gru_unload_context(gts, 1);
++                              return ret;
++                      }
+               }
+               break;
+       case sco_gseg_owner:
+diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
+index 40ac59dd018c..e2325e3d077e 100644
+--- a/drivers/misc/sgi-gru/grumain.c
++++ b/drivers/misc/sgi-gru/grumain.c
+@@ -716,9 +716,10 @@ static int gru_check_chiplet_assignment(struct gru_state *gru,
+  * chiplet. Misassignment can occur if the process migrates to a different
+  * blade or if the user changes the selected blade/chiplet.
+  */
+-void gru_check_context_placement(struct gru_thread_state *gts)
++int gru_check_context_placement(struct gru_thread_state *gts)
+ {
+       struct gru_state *gru;
++      int ret = 0;
+       /*
+        * If the current task is the context owner, verify that the
+@@ -726,15 +727,23 @@ void gru_check_context_placement(struct gru_thread_state *gts)
+        * references. Pthread apps use non-owner references to the CBRs.
+        */
+       gru = gts->ts_gru;
++      /*
++       * If gru or gts->ts_tgid_owner isn't initialized properly, return
++       * success to indicate that the caller does not need to unload the
++       * gru context.The caller is responsible for their inspection and
++       * reinitialization if needed.
++       */
+       if (!gru || gts->ts_tgid_owner != current->tgid)
+-              return;
++              return ret;
+       if (!gru_check_chiplet_assignment(gru, gts)) {
+               STAT(check_context_unload);
+-              gru_unload_context(gts, 1);
++              ret = -EINVAL;
+       } else if (gru_retarget_intr(gts)) {
+               STAT(check_context_retarget_intr);
+       }
++
++      return ret;
+ }
+@@ -934,7 +943,12 @@ vm_fault_t gru_fault(struct vm_fault *vmf)
+       mutex_lock(&gts->ts_ctxlock);
+       preempt_disable();
+-      gru_check_context_placement(gts);
++      if (gru_check_context_placement(gts)) {
++              preempt_enable();
++              mutex_unlock(&gts->ts_ctxlock);
++              gru_unload_context(gts, 1);
++              return VM_FAULT_NOPAGE;
++      }
+       if (!gts->ts_gru) {
+               STAT(load_user_context);
+diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h
+index 5ce8f3081e96..10f0a083b1fa 100644
+--- a/drivers/misc/sgi-gru/grutables.h
++++ b/drivers/misc/sgi-gru/grutables.h
+@@ -637,7 +637,7 @@ extern int gru_user_flush_tlb(unsigned long arg);
+ extern int gru_user_unload_context(unsigned long arg);
+ extern int gru_get_exception_detail(unsigned long arg);
+ extern int gru_set_context_option(unsigned long address);
+-extern void gru_check_context_placement(struct gru_thread_state *gts);
++extern int gru_check_context_placement(struct gru_thread_state *gts);
+ extern int gru_cpu_fault_map_id(void);
+ extern struct vm_area_struct *gru_find_vma(unsigned long vaddr);
+ extern void gru_flush_all_tlb(struct gru_state *gru);
+-- 
+2.35.1
+
diff --git a/queue-5.10/misc-tifm-fix-possible-memory-leak-in-tifm_7xx1_swit.patch b/queue-5.10/misc-tifm-fix-possible-memory-leak-in-tifm_7xx1_swit.patch
new file mode 100644 (file)
index 0000000..0d03a7c
--- /dev/null
@@ -0,0 +1,42 @@
+From 485966728d13e69deb0dc0822d3c05f674d4a4a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 14:47:25 +0800
+Subject: misc: tifm: fix possible memory leak in tifm_7xx1_switch_media()
+
+From: ruanjinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit fd2c930cf6a5b9176382c15f9acb1996e76e25ad ]
+
+If device_register() returns error in tifm_7xx1_switch_media(),
+name of kobject which is allocated in dev_set_name() called in device_add()
+is leaked.
+
+Never directly free @dev after calling device_register(), even
+if it returned an error! Always use put_device() to give up the
+reference initialized.
+
+Fixes: 2428a8fe2261 ("tifm: move common device management tasks from tifm_7xx1 to tifm_core")
+Signed-off-by: ruanjinjie <ruanjinjie@huawei.com>
+Link: https://lore.kernel.org/r/20221117064725.3478402-1-ruanjinjie@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/tifm_7xx1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
+index 228f2eb1d476..2aebbfda104d 100644
+--- a/drivers/misc/tifm_7xx1.c
++++ b/drivers/misc/tifm_7xx1.c
+@@ -190,7 +190,7 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
+                               spin_unlock_irqrestore(&fm->lock, flags);
+                       }
+                       if (sock)
+-                              tifm_free_device(&sock->dev);
++                              put_device(&sock->dev);
+               }
+               spin_lock_irqsave(&fm->lock, flags);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/misdn-hfcmulti-don-t-call-dev_kfree_skb-kfree_skb-un.patch b/queue-5.10/misdn-hfcmulti-don-t-call-dev_kfree_skb-kfree_skb-un.patch
new file mode 100644 (file)
index 0000000..48cb63d
--- /dev/null
@@ -0,0 +1,112 @@
+From 9e42607adb503b5123259ce8885f35a840bf890f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Dec 2022 16:41:39 +0800
+Subject: mISDN: hfcmulti: don't call dev_kfree_skb/kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 1232946cf522b8de9e398828bde325d7c41f29dd ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+skb_queue_purge() is called under spin_lock_irqsave() in handle_dmsg()
+and hfcm_l1callback(), kfree_skb() is called in them, to fix this, use
+skb_queue_splice_init() to move the dch->squeue to a free queue, also
+enqueue the tx_skb and rx_skb, at last calling __skb_queue_purge() to
+free the SKBs afer unlock.
+
+Fixes: af69fb3a8ffa ("Add mISDN HFC multiport driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/isdn/hardware/mISDN/hfcmulti.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
+index 7013a3f08429..4c5b6772562d 100644
+--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
++++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
+@@ -3219,6 +3219,7 @@ static int
+ hfcm_l1callback(struct dchannel *dch, u_int cmd)
+ {
+       struct hfc_multi        *hc = dch->hw;
++      struct sk_buff_head     free_queue;
+       u_long  flags;
+       switch (cmd) {
+@@ -3247,6 +3248,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
+               l1_event(dch->l1, HW_POWERUP_IND);
+               break;
+       case HW_DEACT_REQ:
++              __skb_queue_head_init(&free_queue);
+               /* start deactivation */
+               spin_lock_irqsave(&hc->lock, flags);
+               if (hc->ctype == HFC_TYPE_E1) {
+@@ -3266,20 +3268,21 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
+                               plxsd_checksync(hc, 0);
+                       }
+               }
+-              skb_queue_purge(&dch->squeue);
++              skb_queue_splice_init(&dch->squeue, &free_queue);
+               if (dch->tx_skb) {
+-                      dev_kfree_skb(dch->tx_skb);
++                      __skb_queue_tail(&free_queue, dch->tx_skb);
+                       dch->tx_skb = NULL;
+               }
+               dch->tx_idx = 0;
+               if (dch->rx_skb) {
+-                      dev_kfree_skb(dch->rx_skb);
++                      __skb_queue_tail(&free_queue, dch->rx_skb);
+                       dch->rx_skb = NULL;
+               }
+               test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+               if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
+                       del_timer(&dch->timer);
+               spin_unlock_irqrestore(&hc->lock, flags);
++              __skb_queue_purge(&free_queue);
+               break;
+       case HW_POWERUP_REQ:
+               spin_lock_irqsave(&hc->lock, flags);
+@@ -3386,6 +3389,9 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
+       case PH_DEACTIVATE_REQ:
+               test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
+               if (dch->dev.D.protocol != ISDN_P_TE_S0) {
++                      struct sk_buff_head free_queue;
++
++                      __skb_queue_head_init(&free_queue);
+                       spin_lock_irqsave(&hc->lock, flags);
+                       if (debug & DEBUG_HFCMULTI_MSG)
+                               printk(KERN_DEBUG
+@@ -3407,14 +3413,14 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
+                               /* deactivate */
+                               dch->state = 1;
+                       }
+-                      skb_queue_purge(&dch->squeue);
++                      skb_queue_splice_init(&dch->squeue, &free_queue);
+                       if (dch->tx_skb) {
+-                              dev_kfree_skb(dch->tx_skb);
++                              __skb_queue_tail(&free_queue, dch->tx_skb);
+                               dch->tx_skb = NULL;
+                       }
+                       dch->tx_idx = 0;
+                       if (dch->rx_skb) {
+-                              dev_kfree_skb(dch->rx_skb);
++                              __skb_queue_tail(&free_queue, dch->rx_skb);
+                               dch->rx_skb = NULL;
+                       }
+                       test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+@@ -3426,6 +3432,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
+ #endif
+                       ret = 0;
+                       spin_unlock_irqrestore(&hc->lock, flags);
++                      __skb_queue_purge(&free_queue);
+               } else
+                       ret = l1_event(dch->l1, hh->prim);
+               break;
+-- 
+2.35.1
+
diff --git a/queue-5.10/misdn-hfcpci-don-t-call-dev_kfree_skb-kfree_skb-unde.patch b/queue-5.10/misdn-hfcpci-don-t-call-dev_kfree_skb-kfree_skb-unde.patch
new file mode 100644 (file)
index 0000000..e084164
--- /dev/null
@@ -0,0 +1,71 @@
+From 9d50ea49f9c5b8eb5d12e566310df0e2ff1c4c95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Dec 2022 16:41:38 +0800
+Subject: mISDN: hfcpci: don't call dev_kfree_skb/kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit f0f596bd75a9d573ca9b587abb39cee0b916bb82 ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+skb_queue_purge() is called under spin_lock_irqsave() in hfcpci_l2l1D(),
+kfree_skb() is called in it, to fix this, use skb_queue_splice_init()
+to move the dch->squeue to a free queue, also enqueue the tx_skb and
+rx_skb, at last calling __skb_queue_purge() to free the SKBs afer unlock.
+
+Fixes: 1700fe1a10dc ("Add mISDN HFC PCI driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/isdn/hardware/mISDN/hfcpci.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
+index af17459c1a5c..eba58b99cd29 100644
+--- a/drivers/isdn/hardware/mISDN/hfcpci.c
++++ b/drivers/isdn/hardware/mISDN/hfcpci.c
+@@ -1617,16 +1617,19 @@ hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
+               test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
+               spin_lock_irqsave(&hc->lock, flags);
+               if (hc->hw.protocol == ISDN_P_NT_S0) {
++                      struct sk_buff_head free_queue;
++
++                      __skb_queue_head_init(&free_queue);
+                       /* prepare deactivation */
+                       Write_hfc(hc, HFCPCI_STATES, 0x40);
+-                      skb_queue_purge(&dch->squeue);
++                      skb_queue_splice_init(&dch->squeue, &free_queue);
+                       if (dch->tx_skb) {
+-                              dev_kfree_skb(dch->tx_skb);
++                              __skb_queue_tail(&free_queue, dch->tx_skb);
+                               dch->tx_skb = NULL;
+                       }
+                       dch->tx_idx = 0;
+                       if (dch->rx_skb) {
+-                              dev_kfree_skb(dch->rx_skb);
++                              __skb_queue_tail(&free_queue, dch->rx_skb);
+                               dch->rx_skb = NULL;
+                       }
+                       test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+@@ -1639,10 +1642,12 @@ hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
+                       hc->hw.mst_m &= ~HFCPCI_MASTER;
+                       Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
+                       ret = 0;
++                      spin_unlock_irqrestore(&hc->lock, flags);
++                      __skb_queue_purge(&free_queue);
+               } else {
+                       ret = l1_event(dch->l1, hh->prim);
++                      spin_unlock_irqrestore(&hc->lock, flags);
+               }
+-              spin_unlock_irqrestore(&hc->lock, flags);
+               break;
+       }
+       if (!ret)
+-- 
+2.35.1
+
diff --git a/queue-5.10/misdn-hfcsusb-don-t-call-dev_kfree_skb-kfree_skb-und.patch b/queue-5.10/misdn-hfcsusb-don-t-call-dev_kfree_skb-kfree_skb-und.patch
new file mode 100644 (file)
index 0000000..52bd118
--- /dev/null
@@ -0,0 +1,79 @@
+From cce72cbc3ad1e4c535f2e2cd9c931b722f2628be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Dec 2022 16:41:37 +0800
+Subject: mISDN: hfcsusb: don't call dev_kfree_skb/kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit ddc9648db162eee556edd5222d2808fe33730203 ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+It should use dev_kfree_skb_irq() or dev_consume_skb_irq() instead.
+The difference between them is free reason, dev_kfree_skb_irq() means
+the SKB is dropped in error and dev_consume_skb_irq() means the SKB
+is consumed in normal.
+
+skb_queue_purge() is called under spin_lock_irqsave() in hfcusb_l2l1D(),
+kfree_skb() is called in it, to fix this, use skb_queue_splice_init()
+to move the dch->squeue to a free queue, also enqueue the tx_skb and
+rx_skb, at last calling __skb_queue_purge() to free the SKBs afer unlock.
+
+In tx_iso_complete(), dev_kfree_skb() is called to consume the transmitted
+SKB, so replace it with dev_consume_skb_irq().
+
+Fixes: 69f52adb2d53 ("mISDN: Add HFC USB driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/isdn/hardware/mISDN/hfcsusb.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
+index cd5642cef01f..e8b37bd5e34a 100644
+--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
++++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
+@@ -326,20 +326,24 @@ hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
+               test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
+               if (hw->protocol == ISDN_P_NT_S0) {
++                      struct sk_buff_head free_queue;
++
++                      __skb_queue_head_init(&free_queue);
+                       hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT);
+                       spin_lock_irqsave(&hw->lock, flags);
+-                      skb_queue_purge(&dch->squeue);
++                      skb_queue_splice_init(&dch->squeue, &free_queue);
+                       if (dch->tx_skb) {
+-                              dev_kfree_skb(dch->tx_skb);
++                              __skb_queue_tail(&free_queue, dch->tx_skb);
+                               dch->tx_skb = NULL;
+                       }
+                       dch->tx_idx = 0;
+                       if (dch->rx_skb) {
+-                              dev_kfree_skb(dch->rx_skb);
++                              __skb_queue_tail(&free_queue, dch->rx_skb);
+                               dch->rx_skb = NULL;
+                       }
+                       test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+                       spin_unlock_irqrestore(&hw->lock, flags);
++                      __skb_queue_purge(&free_queue);
+ #ifdef FIXME
+                       if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
+                               dchannel_sched_event(&hc->dch, D_CLEARBUSY);
+@@ -1330,7 +1334,7 @@ tx_iso_complete(struct urb *urb)
+                                       printk("\n");
+                               }
+-                              dev_kfree_skb(tx_skb);
++                              dev_consume_skb_irq(tx_skb);
+                               tx_skb = NULL;
+                               if (fifo->dch && get_next_dframe(fifo->dch))
+                                       tx_skb = fifo->dch->tx_skb;
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-alcor-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-alcor-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..3c122cd
--- /dev/null
@@ -0,0 +1,44 @@
+From 308b7dcaa233340796d4a0a8a744a8fd5f93b9c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 14:30:15 +0800
+Subject: mmc: alcor: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit e93d1468f429475a753d6baa79b853b7ee5ef8c0 ]
+
+mmc_add_host() may return error, if we ignore its return value, the memory
+that allocated in mmc_alloc_host() will be leaked and it will lead a kernel
+crash because of deleting not added device in the remove path.
+
+So fix this by checking the return value and calling mmc_free_host() in the
+error path.
+
+Fixes: c5413ad815a6 ("mmc: add new Alcor Micro Cardreader SD/MMC driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221101063023.1664968-2-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/alcor.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/alcor.c b/drivers/mmc/host/alcor.c
+index bfb8efeb7eb8..d01df01d4b4d 100644
+--- a/drivers/mmc/host/alcor.c
++++ b/drivers/mmc/host/alcor.c
+@@ -1114,7 +1114,10 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev)
+       alcor_hw_init(host);
+       dev_set_drvdata(&pdev->dev, host);
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret)
++              goto free_host;
++
+       return 0;
+ free_host:
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-atmel-mci-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-atmel-mci-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..7721fe3
--- /dev/null
@@ -0,0 +1,60 @@
+From 0d382c60ed8c5c0255c7b034ef78ddb52afc7260 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 20:28:19 +0800
+Subject: mmc: atmel-mci: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 9e6e8c43726673ca2abcaac87640b9215fd72f4c ]
+
+mmc_add_host() may return error, if we ignore its return value,
+it will lead two issues:
+1. The memory that allocated in mmc_alloc_host() is leaked.
+2. In the remove() path, mmc_remove_host() will be called to
+   delete device, but it's not added yet, it will lead a kernel
+   crash because of null-ptr-deref in device_del().
+
+So fix this by checking the return value and calling mmc_free_host()
+in the error path.
+
+Fixes: 7d2be0749a59 ("atmel-mci: Driver for Atmel on-chip MMC controllers")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221108122819.429975-1-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/atmel-mci.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
+index 444bd3a0a922..af85b32c6c1c 100644
+--- a/drivers/mmc/host/atmel-mci.c
++++ b/drivers/mmc/host/atmel-mci.c
+@@ -2223,6 +2223,7 @@ static int atmci_init_slot(struct atmel_mci *host,
+ {
+       struct mmc_host                 *mmc;
+       struct atmel_mci_slot           *slot;
++      int ret;
+       mmc = mmc_alloc_host(sizeof(struct atmel_mci_slot), &host->pdev->dev);
+       if (!mmc)
+@@ -2306,11 +2307,13 @@ static int atmci_init_slot(struct atmel_mci *host,
+       host->slot[id] = slot;
+       mmc_regulator_get_supply(mmc);
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret) {
++              mmc_free_host(mmc);
++              return ret;
++      }
+       if (gpio_is_valid(slot->detect_pin)) {
+-              int ret;
+-
+               timer_setup(&slot->detect_timer, atmci_detect_change, 0);
+               ret = request_irq(gpio_to_irq(slot->detect_pin),
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-f-sdh30-add-quirks-for-broken-timeout-clock-capa.patch b/queue-5.10/mmc-f-sdh30-add-quirks-for-broken-timeout-clock-capa.patch
new file mode 100644 (file)
index 0000000..4c7a8ed
--- /dev/null
@@ -0,0 +1,38 @@
+From d6702c975dae851d8f9e343d875647561570554c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 17:10:33 +0900
+Subject: mmc: f-sdh30: Add quirks for broken timeout clock capability
+
+From: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+
+[ Upstream commit aae9d3a440736691b3c1cb09ae2c32c4f1ee2e67 ]
+
+There is a case where the timeout clock is not supplied to the capability.
+Add a quirk for that.
+
+Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Acked-by: Jassi Brar <jaswinder.singh@linaro.org>
+Link: https://lore.kernel.org/r/20221111081033.3813-7-hayashi.kunihiko@socionext.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci_f_sdh30.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
+index 3f5977979cf2..6c4f43e11282 100644
+--- a/drivers/mmc/host/sdhci_f_sdh30.c
++++ b/drivers/mmc/host/sdhci_f_sdh30.c
+@@ -168,6 +168,9 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
+       if (reg & SDHCI_CAN_DO_8BIT)
+               priv->vendor_hs200 = F_SDH30_EMMC_HS200;
++      if (!(reg & SDHCI_TIMEOUT_CLK_MASK))
++              host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
++
+       ret = sdhci_add_host(host);
+       if (ret)
+               goto err_add_host;
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-meson-gx-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-meson-gx-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..40a2bf2
--- /dev/null
@@ -0,0 +1,47 @@
+From 035b81b42d63ba70024d8178872d7cfb5e6da835 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 20:34:17 +0800
+Subject: mmc: meson-gx: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 90935f16f2650ab7416fa2ffbe5c28cb39cf3f1e ]
+
+mmc_add_host() may return error, if we ignore its return value,
+it will lead two issues:
+1. The memory that allocated in mmc_alloc_host() is leaked.
+2. In the remove() path, mmc_remove_host() will be called to
+   delete device, but it's not added yet, it will lead a kernel
+   crash because of null-ptr-deref in device_del().
+
+Fix this by checking the return value and goto error path which
+will call mmc_free_host().
+
+Fixes: 51c5d8447bd7 ("MMC: meson: initial support for GX platforms")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20221108123417.479045-1-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/meson-gx-mmc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
+index bccc85b3fc50..19a6b55e344f 100644
+--- a/drivers/mmc/host/meson-gx-mmc.c
++++ b/drivers/mmc/host/meson-gx-mmc.c
+@@ -1280,7 +1280,9 @@ static int meson_mmc_probe(struct platform_device *pdev)
+       }
+       mmc->ops = &meson_mmc_ops;
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret)
++              goto err_free_irq;
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-mmci-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-mmci-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..62ead85
--- /dev/null
@@ -0,0 +1,46 @@
+From 0f71d908b69bf2a6671479533833c6a8d2724290 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 21:35:39 +0800
+Subject: mmc: mmci: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit b38a20f29a49ae04d23750d104b25400b792b98c ]
+
+mmc_add_host() may return error, if we ignore its return value,
+it will lead two issues:
+1. The memory that allocated in mmc_alloc_host() is leaked.
+2. In the remove() path, mmc_remove_host() will be called to
+   delete device, but it's not added yet, it will lead a kernel
+   crash because of null-ptr-deref in device_del().
+
+So fix this by checking the return value and goto error path which
+will call mmc_free_host().
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221109133539.3275664-1-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/mmci.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
+index b5684e5d79e6..5d83c8e7bf5c 100644
+--- a/drivers/mmc/host/mmci.c
++++ b/drivers/mmc/host/mmci.c
+@@ -2191,7 +2191,9 @@ static int mmci_probe(struct amba_device *dev,
+       pm_runtime_set_autosuspend_delay(&dev->dev, 50);
+       pm_runtime_use_autosuspend(&dev->dev);
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret)
++              goto clk_disable;
+       pm_runtime_put(&dev->dev);
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-moxart-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-moxart-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..739b0db
--- /dev/null
@@ -0,0 +1,43 @@
+From 28dbd81d634fe479e0de9a63005b5c61e9633646 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 14:30:16 +0800
+Subject: mmc: moxart: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 0ca18d09c744fb030ae9bc5836c3e357e0237dea ]
+
+mmc_add_host() may return error, if we ignore its return value, the memory
+that allocated in mmc_alloc_host() will be leaked and it will lead a kernel
+crash because of deleting not added device in the remove path.
+
+So fix this by checking the return value and goto error path which will call
+mmc_free_host().
+
+Fixes: 1b66e94e6b99 ("mmc: moxart: Add MOXA ART SD/MMC driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221101063023.1664968-3-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/moxart-mmc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c
+index c16300b92139..fb96bb76eefb 100644
+--- a/drivers/mmc/host/moxart-mmc.c
++++ b/drivers/mmc/host/moxart-mmc.c
+@@ -668,7 +668,9 @@ static int moxart_probe(struct platform_device *pdev)
+               goto out;
+       dev_set_drvdata(dev, mmc);
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret)
++              goto out;
+       dev_dbg(dev, "IRQ=%d, FIFO is %d bytes\n", irq, host->fifo_width);
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-mxcmmc-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-mxcmmc-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..7b69bdc
--- /dev/null
@@ -0,0 +1,43 @@
+From 122111866cb14600279950ca4027520a44a6611a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 14:30:17 +0800
+Subject: mmc: mxcmmc: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit cde600af7b413c9fe03e85c58c4279df90e91d13 ]
+
+mmc_add_host() may return error, if we ignore its return value, the memory
+that allocated in mmc_alloc_host() will be leaked and it will lead a kernel
+crash because of deleting not added device in the remove path.
+
+So fix this by checking the return value and goto error path which will call
+mmc_free_host().
+
+Fixes: d96be879ff46 ("mmc: Add a MX2/MX3 specific SDHC driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221101063023.1664968-4-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/mxcmmc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
+index 12ee07285980..93a105b07564 100644
+--- a/drivers/mmc/host/mxcmmc.c
++++ b/drivers/mmc/host/mxcmmc.c
+@@ -1167,7 +1167,9 @@ static int mxcmci_probe(struct platform_device *pdev)
+       timer_setup(&host->watchdog, mxcmci_watchdog, 0);
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret)
++              goto out_free_dma;
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-omap_hsmmc-fix-return-value-check-of-mmc_add_hos.patch b/queue-5.10/mmc-omap_hsmmc-fix-return-value-check-of-mmc_add_hos.patch
new file mode 100644 (file)
index 0000000..423e204
--- /dev/null
@@ -0,0 +1,46 @@
+From 8a17d1e249f19444eb47e11039f9b68ce9be1ab3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 20:13:16 +0800
+Subject: mmc: omap_hsmmc: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit a525cad241c339ca00bf7ebf03c5180f2a9b767c ]
+
+mmc_add_host() may return error, if we ignore its return value,
+it will lead two issues:
+1. The memory that allocated in mmc_alloc_host() is leaked.
+2. In the remove() path, mmc_remove_host() will be called to
+   delete device, but it's not added yet, it will lead a kernel
+   crash because of null-ptr-deref in device_del().
+
+Fix this by checking the return value and goto error path wihch
+will call mmc_free_host().
+
+Fixes: a45c6cb81647 ("[ARM] 5369/1: omap mmc: Add new omap hsmmc controller for 2430 and 34xx, v3")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221108121316.340354-1-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/omap_hsmmc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
+index aa9cc49206d1..5b6ede81fc9f 100644
+--- a/drivers/mmc/host/omap_hsmmc.c
++++ b/drivers/mmc/host/omap_hsmmc.c
+@@ -1987,7 +1987,9 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+       if (!ret)
+               mmc->caps |= MMC_CAP_SDIO_IRQ;
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret)
++              goto err_irq;
+       if (mmc_pdata(host)->name != NULL) {
+               ret = device_create_file(&mmc->class_dev, &dev_attr_slot_name);
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-pxamci-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-pxamci-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..7563157
--- /dev/null
@@ -0,0 +1,46 @@
+From 32024d16f5152bbf187531eef99db4b67c297998 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 14:30:18 +0800
+Subject: mmc: pxamci: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 80e1ef3afb8bfbe768380b70ffe1b6cab87d1a3b ]
+
+mmc_add_host() may return error, if we ignore its return value, the memory
+that allocated in mmc_alloc_host() will be leaked and it will lead a kernel
+crash because of deleting not added device in the remove path.
+
+So fix this by checking the return value and goto error path which will call
+mmc_free_host(), besides, ->exit() need be called to uninit the pdata.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221101063023.1664968-5-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/pxamci.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
+index 55868b6b8658..e25e9bb34eb3 100644
+--- a/drivers/mmc/host/pxamci.c
++++ b/drivers/mmc/host/pxamci.c
+@@ -763,7 +763,12 @@ static int pxamci_probe(struct platform_device *pdev)
+                       dev_warn(dev, "gpio_ro and get_ro() both defined\n");
+       }
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret) {
++              if (host->pdata && host->pdata->exit)
++                      host->pdata->exit(dev, mmc);
++              goto out;
++      }
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-renesas_sdhi-better-reset-from-hs400-mode.patch b/queue-5.10/mmc-renesas_sdhi-better-reset-from-hs400-mode.patch
new file mode 100644 (file)
index 0000000..8b652c8
--- /dev/null
@@ -0,0 +1,40 @@
+From c904e27acec86dbbddb575b2ca7cf8ee399d2f64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Nov 2022 12:34:55 +0100
+Subject: mmc: renesas_sdhi: better reset from HS400 mode
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 0da69dd2155019ed4c444ede0e79ce7a4a6af627 ]
+
+Up to now, HS400 adjustment mode was only disabled on soft reset when a
+calibration table was in use. It is safer, though, to disable it as soon
+as the instance has an adjustment related quirk set, i.e. bad taps or a
+calibration table.
+
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Link: https://lore.kernel.org/r/20221120113457.42010-3-wsa+renesas@sang-engineering.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/renesas_sdhi_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
+index ac01fb518386..a49b8fe2a098 100644
+--- a/drivers/mmc/host/renesas_sdhi_core.c
++++ b/drivers/mmc/host/renesas_sdhi_core.c
+@@ -537,7 +537,7 @@ static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,
+                        SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) &
+                       sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));
+-      if (priv->adjust_hs400_calib_table)
++      if (priv->quirks && (priv->quirks->hs400_calib_table || priv->quirks->hs400_bad_taps))
+               renesas_sdhi_adjust_hs400_mode_disable(host);
+       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-rtsx_usb_sdmmc-fix-return-value-check-of-mmc_add.patch b/queue-5.10/mmc-rtsx_usb_sdmmc-fix-return-value-check-of-mmc_add.patch
new file mode 100644 (file)
index 0000000..20f7e63
--- /dev/null
@@ -0,0 +1,58 @@
+From 7810495307cf50544a3daad9a191c045f16336d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 14:30:20 +0800
+Subject: mmc: rtsx_usb_sdmmc: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit fc38a5a10e9e5a75eb9189854abeb8405b214cc9 ]
+
+mmc_add_host() may return error, if we ignore its return value, the memory
+that allocated in mmc_alloc_host() will be leaked and it will lead a kernel
+crash because of deleting not added device in the remove path.
+
+So fix this by checking the return value and calling mmc_free_host() in the
+error path, besides, led_classdev_unregister() and pm_runtime_disable() also
+need be called.
+
+Fixes: c7f6558d84af ("mmc: Add realtek USB sdmmc host driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221101063023.1664968-7-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/rtsx_usb_sdmmc.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
+index 5fe4528e296e..1be3a355f10d 100644
+--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
++++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
+@@ -1332,6 +1332,7 @@ static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
+ #ifdef RTSX_USB_USE_LEDS_CLASS
+       int err;
+ #endif
++      int ret;
+       ucr = usb_get_intfdata(to_usb_interface(pdev->dev.parent));
+       if (!ucr)
+@@ -1368,7 +1369,15 @@ static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
+       INIT_WORK(&host->led_work, rtsx_usb_update_led);
+ #endif
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret) {
++#ifdef RTSX_USB_USE_LEDS_CLASS
++              led_classdev_unregister(&host->led);
++#endif
++              mmc_free_host(mmc);
++              pm_runtime_disable(&pdev->dev);
++              return ret;
++      }
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-toshsd-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-toshsd-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..5bcf145
--- /dev/null
@@ -0,0 +1,52 @@
+From 48816c4ea5fabea27c3754aac6199566992e6c90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 14:30:21 +0800
+Subject: mmc: toshsd: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit f670744a316ea983113a65313dcd387b5a992444 ]
+
+mmc_add_host() may return error, if we ignore its return value, the memory
+that allocated in mmc_alloc_host() will be leaked and it will lead a kernel
+crash because of deleting not added device in the remove path.
+
+So fix this by checking the return value and goto error path which will call
+mmc_free_host(), besides, free_irq() also needs be called.
+
+Fixes: a5eb8bbd66cc ("mmc: add Toshiba PCI SD controller driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221101063023.1664968-8-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/toshsd.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/toshsd.c b/drivers/mmc/host/toshsd.c
+index 8d037c2071ab..497791ffada6 100644
+--- a/drivers/mmc/host/toshsd.c
++++ b/drivers/mmc/host/toshsd.c
+@@ -651,7 +651,9 @@ static int toshsd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+       if (ret)
+               goto unmap;
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret)
++              goto free_irq;
+       base = pci_resource_start(pdev, 0);
+       dev_dbg(&pdev->dev, "MMIO %pa, IRQ %d\n", &base, pdev->irq);
+@@ -660,6 +662,8 @@ static int toshsd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+       return 0;
++free_irq:
++      free_irq(pdev->irq, host);
+ unmap:
+       pci_iounmap(pdev, host->ioaddr);
+ release:
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-via-sdmmc-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-via-sdmmc-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..53a4ff8
--- /dev/null
@@ -0,0 +1,46 @@
+From a0f996e498700f6d6b4a761ac1cf17877f80fd29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 21:09:49 +0800
+Subject: mmc: via-sdmmc: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit e4e46fb61e3bb4628170810d3f2b996b709b90d9 ]
+
+mmc_add_host() may return error, if we ignore its return value,
+it will lead two issues:
+1. The memory that allocated in mmc_alloc_host() is leaked.
+2. In the remove() path, mmc_remove_host() will be called to
+   delete device, but it's not added yet, it will lead a kernel
+   crash because of null-ptr-deref in device_del().
+
+Fix this by checking the return value and goto error path which
+will call mmc_free_host().
+
+Fixes: f0bf7f61b840 ("mmc: Add new via-sdmmc host controller driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221108130949.1067699-1-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/via-sdmmc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
+index f07c71db3caf..f6b525fb5c0e 100644
+--- a/drivers/mmc/host/via-sdmmc.c
++++ b/drivers/mmc/host/via-sdmmc.c
+@@ -1154,7 +1154,9 @@ static int via_sd_probe(struct pci_dev *pcidev,
+           pcidev->subsystem_device == 0x3891)
+               sdhost->quirks = VIA_CRDR_QUIRK_300MS_PWRDELAY;
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret)
++              goto unmap;
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-vub300-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-vub300-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..c708eb5
--- /dev/null
@@ -0,0 +1,67 @@
+From 744cb4af98248def688e127afece49980b9f7011 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 14:30:22 +0800
+Subject: mmc: vub300: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 0613ad2401f88bdeae5594c30afe318e93b14676 ]
+
+mmc_add_host() may return error, if we ignore its return value, the memory
+that allocated in mmc_alloc_host() will be leaked and it will lead a kernel
+crash because of deleting not added device in the remove path.
+
+So fix this by checking the return value and goto error path which will call
+mmc_free_host(), besides, the timer added before mmc_add_host() needs be del.
+
+And this patch fixes another missing call mmc_free_host() if usb_control_msg()
+fails.
+
+Fixes: 88095e7b473a ("mmc: Add new VUB300 USB-to-SD/SDIO/MMC driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221101063023.1664968-9-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/vub300.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
+index 97beece62fec..ab36ec479747 100644
+--- a/drivers/mmc/host/vub300.c
++++ b/drivers/mmc/host/vub300.c
+@@ -2299,14 +2299,14 @@ static int vub300_probe(struct usb_interface *interface,
+                               0x0000, 0x0000, &vub300->system_port_status,
+                               sizeof(vub300->system_port_status), 1000);
+       if (retval < 0) {
+-              goto error4;
++              goto error5;
+       } else if (sizeof(vub300->system_port_status) == retval) {
+               vub300->card_present =
+                       (0x0001 & vub300->system_port_status.port_flags) ? 1 : 0;
+               vub300->read_only =
+                       (0x0010 & vub300->system_port_status.port_flags) ? 1 : 0;
+       } else {
+-              goto error4;
++              goto error5;
+       }
+       usb_set_intfdata(interface, vub300);
+       INIT_DELAYED_WORK(&vub300->pollwork, vub300_pollwork_thread);
+@@ -2329,8 +2329,13 @@ static int vub300_probe(struct usb_interface *interface,
+                        "USB vub300 remote SDIO host controller[%d]"
+                        "connected with no SD/SDIO card inserted\n",
+                        interface_to_InterfaceNumber(interface));
+-      mmc_add_host(mmc);
++      retval = mmc_add_host(mmc);
++      if (retval)
++              goto error6;
++
+       return 0;
++error6:
++      del_timer_sync(&vub300->inactivity_timer);
+ error5:
+       mmc_free_host(mmc);
+       /*
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-wbsd-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-wbsd-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..6578f3f
--- /dev/null
@@ -0,0 +1,55 @@
+From 5dd328b4535745a58178db0a6240ffe7501873f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 21:32:37 +0800
+Subject: mmc: wbsd: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit dc5b9b50fc9d1334407e316e6e29a5097ef833bd ]
+
+mmc_add_host() may return error, if we ignore its return value,
+it will lead two issues:
+1. The memory that allocated in mmc_alloc_host() is leaked.
+2. In the remove() path, mmc_remove_host() will be called to
+   delete device, but it's not added yet, it will lead a kernel
+   crash because of null-ptr-deref in device_del().
+
+So fix this by checking the return value and goto error path which
+will call mmc_free_host(), besides, other resources also need be
+released.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221109133237.3273558-1-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/wbsd.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
+index cd63ea865b77..f3090216e0dc 100644
+--- a/drivers/mmc/host/wbsd.c
++++ b/drivers/mmc/host/wbsd.c
+@@ -1703,7 +1703,17 @@ static int wbsd_init(struct device *dev, int base, int irq, int dma,
+        */
+       wbsd_init_device(host);
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret) {
++              if (!pnp)
++                      wbsd_chip_poweroff(host);
++
++              wbsd_release_resources(host);
++              wbsd_free_mmc(dev);
++
++              mmc_free_host(mmc);
++              return ret;
++      }
+       pr_info("%s: W83L51xD", mmc_hostname(mmc));
+       if (host->chip_id != 0)
+-- 
+2.35.1
+
diff --git a/queue-5.10/mmc-wmt-sdmmc-fix-return-value-check-of-mmc_add_host.patch b/queue-5.10/mmc-wmt-sdmmc-fix-return-value-check-of-mmc_add_host.patch
new file mode 100644 (file)
index 0000000..2a50551
--- /dev/null
@@ -0,0 +1,49 @@
+From 6bd8af49d54736025942ee695910bd9486a8cbec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 14:30:23 +0800
+Subject: mmc: wmt-sdmmc: fix return value check of mmc_add_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 29276d56f6ed138db0f38cd31aedc0b725c8c76c ]
+
+mmc_add_host() may return error, if we ignore its return value, the memory
+that allocated in mmc_alloc_host() will be leaked and it will lead a kernel
+crash because of deleting not added device in the remove path.
+
+So fix this by checking the return value and goto error path which will call
+mmc_free_host(), besides, clk_disable_unprepare() also needs be called.
+
+Fixes: 3a96dff0f828 ("mmc: SD/MMC Host Controller for Wondermedia WM8505/WM8650")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221101063023.1664968-10-yangyingliang@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/wmt-sdmmc.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c
+index 8df722ec57ed..393319548857 100644
+--- a/drivers/mmc/host/wmt-sdmmc.c
++++ b/drivers/mmc/host/wmt-sdmmc.c
+@@ -859,11 +859,15 @@ static int wmt_mci_probe(struct platform_device *pdev)
+       /* configure the controller to a known 'ready' state */
+       wmt_reset_hardware(mmc);
+-      mmc_add_host(mmc);
++      ret = mmc_add_host(mmc);
++      if (ret)
++              goto fail7;
+       dev_info(&pdev->dev, "WMT SDHC Controller initialized\n");
+       return 0;
++fail7:
++      clk_disable_unprepare(priv->clk_sdmmc);
+ fail6:
+       clk_put(priv->clk_sdmmc);
+ fail5_and_a_half:
+-- 
+2.35.1
+
diff --git a/queue-5.10/mrp-introduce-active-flags-to-prevent-uaf-when-appli.patch b/queue-5.10/mrp-introduce-active-flags-to-prevent-uaf-when-appli.patch
new file mode 100644 (file)
index 0000000..8e999a8
--- /dev/null
@@ -0,0 +1,126 @@
+From 47e778106d41cccf99db3039f9f06f0c528af541 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 19:45:11 +0800
+Subject: mrp: introduce active flags to prevent UAF when applicant uninit
+
+From: Schspa Shi <schspa@gmail.com>
+
+[ Upstream commit ab0377803dafc58f1e22296708c1c28e309414d6 ]
+
+The caller of del_timer_sync must prevent restarting of the timer, If
+we have no this synchronization, there is a small probability that the
+cancellation will not be successful.
+
+And syzbot report the fellowing crash:
+==================================================================
+BUG: KASAN: use-after-free in hlist_add_head include/linux/list.h:929 [inline]
+BUG: KASAN: use-after-free in enqueue_timer+0x18/0xa4 kernel/time/timer.c:605
+Write at addr f9ff000024df6058 by task syz-fuzzer/2256
+Pointer tag: [f9], memory tag: [fe]
+
+CPU: 1 PID: 2256 Comm: syz-fuzzer Not tainted 6.1.0-rc5-syzkaller-00008-
+ge01d50cbd6ee #0
+Hardware name: linux,dummy-virt (DT)
+Call trace:
+ dump_backtrace.part.0+0xe0/0xf0 arch/arm64/kernel/stacktrace.c:156
+ dump_backtrace arch/arm64/kernel/stacktrace.c:162 [inline]
+ show_stack+0x18/0x40 arch/arm64/kernel/stacktrace.c:163
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x68/0x84 lib/dump_stack.c:106
+ print_address_description mm/kasan/report.c:284 [inline]
+ print_report+0x1a8/0x4a0 mm/kasan/report.c:395
+ kasan_report+0x94/0xb4 mm/kasan/report.c:495
+ __do_kernel_fault+0x164/0x1e0 arch/arm64/mm/fault.c:320
+ do_bad_area arch/arm64/mm/fault.c:473 [inline]
+ do_tag_check_fault+0x78/0x8c arch/arm64/mm/fault.c:749
+ do_mem_abort+0x44/0x94 arch/arm64/mm/fault.c:825
+ el1_abort+0x40/0x60 arch/arm64/kernel/entry-common.c:367
+ el1h_64_sync_handler+0xd8/0xe4 arch/arm64/kernel/entry-common.c:427
+ el1h_64_sync+0x64/0x68 arch/arm64/kernel/entry.S:576
+ hlist_add_head include/linux/list.h:929 [inline]
+ enqueue_timer+0x18/0xa4 kernel/time/timer.c:605
+ mod_timer+0x14/0x20 kernel/time/timer.c:1161
+ mrp_periodic_timer_arm net/802/mrp.c:614 [inline]
+ mrp_periodic_timer+0xa0/0xc0 net/802/mrp.c:627
+ call_timer_fn.constprop.0+0x24/0x80 kernel/time/timer.c:1474
+ expire_timers+0x98/0xc4 kernel/time/timer.c:1519
+
+To fix it, we can introduce a new active flags to make sure the timer will
+not restart.
+
+Reported-by: syzbot+6fd64001c20aa99e34a4@syzkaller.appspotmail.com
+
+Signed-off-by: Schspa Shi <schspa@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/mrp.h |  1 +
+ net/802/mrp.c     | 18 +++++++++++++-----
+ 2 files changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/mrp.h b/include/net/mrp.h
+index 1c308c034e1a..a8102661fd61 100644
+--- a/include/net/mrp.h
++++ b/include/net/mrp.h
+@@ -120,6 +120,7 @@ struct mrp_applicant {
+       struct sk_buff          *pdu;
+       struct rb_root          mad;
+       struct rcu_head         rcu;
++      bool                    active;
+ };
+ struct mrp_port {
+diff --git a/net/802/mrp.c b/net/802/mrp.c
+index 35e04cc5390c..c10a432a5b43 100644
+--- a/net/802/mrp.c
++++ b/net/802/mrp.c
+@@ -606,7 +606,10 @@ static void mrp_join_timer(struct timer_list *t)
+       spin_unlock(&app->lock);
+       mrp_queue_xmit(app);
+-      mrp_join_timer_arm(app);
++      spin_lock(&app->lock);
++      if (likely(app->active))
++              mrp_join_timer_arm(app);
++      spin_unlock(&app->lock);
+ }
+ static void mrp_periodic_timer_arm(struct mrp_applicant *app)
+@@ -620,11 +623,12 @@ static void mrp_periodic_timer(struct timer_list *t)
+       struct mrp_applicant *app = from_timer(app, t, periodic_timer);
+       spin_lock(&app->lock);
+-      mrp_mad_event(app, MRP_EVENT_PERIODIC);
+-      mrp_pdu_queue(app);
++      if (likely(app->active)) {
++              mrp_mad_event(app, MRP_EVENT_PERIODIC);
++              mrp_pdu_queue(app);
++              mrp_periodic_timer_arm(app);
++      }
+       spin_unlock(&app->lock);
+-
+-      mrp_periodic_timer_arm(app);
+ }
+ static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset)
+@@ -872,6 +876,7 @@ int mrp_init_applicant(struct net_device *dev, struct mrp_application *appl)
+       app->dev = dev;
+       app->app = appl;
+       app->mad = RB_ROOT;
++      app->active = true;
+       spin_lock_init(&app->lock);
+       skb_queue_head_init(&app->queue);
+       rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app);
+@@ -900,6 +905,9 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
+       RCU_INIT_POINTER(port->applicants[appl->type], NULL);
++      spin_lock_bh(&app->lock);
++      app->active = false;
++      spin_unlock_bh(&app->lock);
+       /* Delete timer and generate a final TX event to flush out
+        * all pending messages before the applicant is gone.
+        */
+-- 
+2.35.1
+
diff --git a/queue-5.10/mtd-fix-device-name-leak-when-register-device-failed.patch b/queue-5.10/mtd-fix-device-name-leak-when-register-device-failed.patch
new file mode 100644 (file)
index 0000000..3ab0e6a
--- /dev/null
@@ -0,0 +1,62 @@
+From 7d6d70ca20b3f164ed8ecde972a6a5993eba8d21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Oct 2022 20:13:52 +0800
+Subject: mtd: Fix device name leak when register device failed in
+ add_mtd_device()
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+[ Upstream commit 895d68a39481a75c680aa421546931fb11942fa6 ]
+
+There is a kmemleak when register device failed:
+  unreferenced object 0xffff888101aab550 (size 8):
+    comm "insmod", pid 3922, jiffies 4295277753 (age 925.408s)
+    hex dump (first 8 bytes):
+      6d 74 64 30 00 88 ff ff                          mtd0....
+    backtrace:
+      [<00000000bde26724>] __kmalloc_node_track_caller+0x4e/0x150
+      [<000000003c32b416>] kvasprintf+0xb0/0x130
+      [<000000001f7a8f15>] kobject_set_name_vargs+0x2f/0xb0
+      [<000000006e781163>] dev_set_name+0xab/0xe0
+      [<00000000e30d0c78>] add_mtd_device+0x4bb/0x700
+      [<00000000f3d34de7>] mtd_device_parse_register+0x2ac/0x3f0
+      [<00000000c0d88488>] 0xffffffffa0238457
+      [<00000000b40d0922>] 0xffffffffa02a008f
+      [<0000000023d17b9d>] do_one_initcall+0x87/0x2a0
+      [<00000000770f6ca6>] do_init_module+0xdf/0x320
+      [<000000007b6768fe>] load_module+0x2f98/0x3330
+      [<00000000346bed5a>] __do_sys_finit_module+0x113/0x1b0
+      [<00000000674c2290>] do_syscall_64+0x35/0x80
+      [<000000004c6a8d97>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+If register device failed, should call put_device() to give up the
+reference.
+
+Fixes: 1f24b5a8ecbb ("[MTD] driver model updates")
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20221022121352.2534682-1-zhangxiaoxu5@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdcore.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index a5197a481902..b2d88ff90e93 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -667,8 +667,10 @@ int add_mtd_device(struct mtd_info *mtd)
+       dev_set_drvdata(&mtd->dev, mtd);
+       of_node_get(mtd_get_of_node(mtd));
+       error = device_register(&mtd->dev);
+-      if (error)
++      if (error) {
++              put_device(&mtd->dev);
+               goto fail_added;
++      }
+       /* Add the nvmem provider */
+       error = mtd_nvmem_add(mtd);
+-- 
+2.35.1
+
diff --git a/queue-5.10/mtd-lpddr2_nvm-fix-possible-null-ptr-deref.patch b/queue-5.10/mtd-lpddr2_nvm-fix-possible-null-ptr-deref.patch
new file mode 100644 (file)
index 0000000..4ed5e94
--- /dev/null
@@ -0,0 +1,41 @@
+From a03da3ab193f8ab2a0af9f07e804823e372cfd4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 17:02:40 +0800
+Subject: mtd: lpddr2_nvm: Fix possible null-ptr-deref
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Hui Tang <tanghui20@huawei.com>
+
+[ Upstream commit 6bdd45d795adf9e73b38ced5e7f750cd199499ff ]
+
+It will cause null-ptr-deref when resource_size(add_range) invoked,
+if platform_get_resource() returns NULL.
+
+Fixes: 96ba9dd65788 ("mtd: lpddr: add driver for LPDDR2-NVM PCM memories")
+Signed-off-by: Hui Tang <tanghui20@huawei.com>
+Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20221114090240.244172-1-tanghui20@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/lpddr/lpddr2_nvm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/mtd/lpddr/lpddr2_nvm.c b/drivers/mtd/lpddr/lpddr2_nvm.c
+index 72f5c7b30079..add4386f99f0 100644
+--- a/drivers/mtd/lpddr/lpddr2_nvm.c
++++ b/drivers/mtd/lpddr/lpddr2_nvm.c
+@@ -433,6 +433,8 @@ static int lpddr2_nvm_probe(struct platform_device *pdev)
+       /* lpddr2_nvm address range */
+       add_range = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!add_range)
++              return -ENODEV;
+       /* Populate map_info data structure */
+       *map = (struct map_info) {
+-- 
+2.35.1
+
diff --git a/queue-5.10/mtd-maps-pxa2xx-flash-fix-memory-leak-in-probe.patch b/queue-5.10/mtd-maps-pxa2xx-flash-fix-memory-leak-in-probe.patch
new file mode 100644 (file)
index 0000000..728857e
--- /dev/null
@@ -0,0 +1,44 @@
+From 8604c62af79698e8d2729879c940b93e732f35a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Nov 2022 07:33:07 +0000
+Subject: mtd: maps: pxa2xx-flash: fix memory leak in probe
+
+From: Zheng Yongjun <zhengyongjun3@huawei.com>
+
+[ Upstream commit 2399401feee27c639addc5b7e6ba519d3ca341bf ]
+
+Free 'info' upon remapping error to avoid a memory leak.
+
+Fixes: e644f7d62894 ("[MTD] MAPS: Merge Lubbock and Mainstone drivers into common PXA2xx driver")
+Signed-off-by: Zheng Yongjun <zhengyongjun3@huawei.com>
+[<miquel.raynal@bootlin.com>: Reword the commit log]
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20221119073307.22929-1-zhengyongjun3@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/maps/pxa2xx-flash.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
+index 7d96758a8f04..6e5e55755970 100644
+--- a/drivers/mtd/maps/pxa2xx-flash.c
++++ b/drivers/mtd/maps/pxa2xx-flash.c
+@@ -66,6 +66,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev)
+       if (!info->map.virt) {
+               printk(KERN_WARNING "Failed to ioremap %s\n",
+                      info->map.name);
++              kfree(info);
+               return -ENOMEM;
+       }
+       info->map.cached = ioremap_cache(info->map.phys, info->map.size);
+@@ -87,6 +88,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev)
+               iounmap((void *)info->map.virt);
+               if (info->map.cached)
+                       iounmap(info->map.cached);
++              kfree(info);
+               return -EIO;
+       }
+       info->mtd->dev.parent = &pdev->dev;
+-- 
+2.35.1
+
diff --git a/queue-5.10/myri10ge-fix-an-error-handling-path-in-myri10ge_prob.patch b/queue-5.10/myri10ge-fix-an-error-handling-path-in-myri10ge_prob.patch
new file mode 100644 (file)
index 0000000..869a9e7
--- /dev/null
@@ -0,0 +1,37 @@
+From 03e92352587204f3ccc693a0da368463611cc692 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Dec 2022 19:08:40 +0100
+Subject: myri10ge: Fix an error handling path in myri10ge_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit d83b950d44d2982c0e62e3d81b0f35ab09431008 ]
+
+Some memory allocated in myri10ge_probe_slices() is not released in the
+error handling path of myri10ge_probe().
+
+Add the corresponding kfree(), as already done in the remove function.
+
+Fixes: 0dcffac1a329 ("myri10ge: add multislices support")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+index 1664e9184c9c..5a1ed4818baa 100644
+--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
++++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+@@ -3920,6 +3920,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+       myri10ge_free_slices(mgp);
+ abort_with_firmware:
++      kfree(mgp->msix_vectors);
+       myri10ge_dummy_rdma(mgp, 0);
+ abort_with_ioremap:
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-add-a-helper-to-avoid-issues-with-hw-tx-timestam.patch b/queue-5.10/net-add-a-helper-to-avoid-issues-with-hw-tx-timestam.patch
new file mode 100644 (file)
index 0000000..6fac7d3
--- /dev/null
@@ -0,0 +1,108 @@
+From 4e060899d1f3c0d4e5eb0f99c105953dca46eeb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Mar 2021 16:50:44 +0200
+Subject: net: add a helper to avoid issues with HW TX timestamping and
+ SO_TXTIME
+
+From: Vladimir Oltean <olteanv@gmail.com>
+
+[ Upstream commit 847cbfc014adafeac401e19e349b0fd524f201c3 ]
+
+As explained in commit 29d98f54a4fe ("net: enetc: allow hardware
+timestamping on TX queues with tc-etf enabled"), hardware TX
+timestamping requires an skb with skb->tstamp = 0. When a packet is sent
+with SO_TXTIME, the skb->skb_mstamp_ns corrupts the value of skb->tstamp,
+so the drivers need to explicitly reset skb->tstamp to zero after
+consuming the TX time.
+
+Create a helper named skb_txtime_consumed() which does just that. All
+drivers which offload TC_SETUP_QDISC_ETF should implement it, and it
+would make it easier to assess during review whether they do the right
+thing in order to be compatible with hardware timestamping or not.
+
+Suggested-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: db0b124f02ba ("igc: Enhance Qbv scheduling by using first flag bit")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 8 ++------
+ drivers/net/ethernet/intel/igb/igb_main.c    | 2 +-
+ drivers/net/ethernet/intel/igc/igc_main.c    | 2 +-
+ include/net/pkt_sched.h                      | 9 +++++++++
+ 4 files changed, 13 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index 975762ccb66f..5f9603d4c049 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -5,6 +5,7 @@
+ #include <linux/tcp.h>
+ #include <linux/udp.h>
+ #include <linux/vmalloc.h>
++#include <net/pkt_sched.h>
+ /* ENETC overhead: optional extension BD + 1 BD gap */
+ #define ENETC_TXBDS_NEEDED(val)       ((val) + 2)
+@@ -384,12 +385,7 @@ static void enetc_tstamp_tx(struct sk_buff *skb, u64 tstamp)
+       if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) {
+               memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+               shhwtstamps.hwtstamp = ns_to_ktime(tstamp);
+-              /* Ensure skb_mstamp_ns, which might have been populated with
+-               * the txtime, is not mistaken for a software timestamp,
+-               * because this will prevent the dispatch of our hardware
+-               * timestamp to the socket.
+-               */
+-              skb->tstamp = ktime_set(0, 0);
++              skb_txtime_consumed(skb);
+               skb_tstamp_tx(skb, &shhwtstamps);
+       }
+ }
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index f24f1a8ec2fb..2646601c3487 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -5879,7 +5879,7 @@ static void igb_tx_ctxtdesc(struct igb_ring *tx_ring,
+        */
+       if (tx_ring->launchtime_enable) {
+               ts = ktime_to_timespec64(first->skb->tstamp);
+-              first->skb->tstamp = ktime_set(0, 0);
++              skb_txtime_consumed(first->skb);
+               context_desc->seqnum_seed = cpu_to_le32(ts.tv_nsec / 32);
+       } else {
+               context_desc->seqnum_seed = 0;
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index f438cdf83e55..48192594d3d7 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -946,7 +946,7 @@ static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
+               struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
+               ktime_t txtime = first->skb->tstamp;
+-              first->skb->tstamp = ktime_set(0, 0);
++              skb_txtime_consumed(first->skb);
+               context_desc->launch_time = igc_tx_launchtime(adapter,
+                                                             txtime);
+       } else {
+diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
+index 7e58b4470570..50d5ffbad473 100644
+--- a/include/net/pkt_sched.h
++++ b/include/net/pkt_sched.h
+@@ -179,4 +179,13 @@ struct tc_taprio_qopt_offload *taprio_offload_get(struct tc_taprio_qopt_offload
+                                                 *offload);
+ void taprio_offload_free(struct tc_taprio_qopt_offload *offload);
++/* Ensure skb_mstamp_ns, which might have been populated with the txtime, is
++ * not mistaken for a software timestamp, because this will otherwise prevent
++ * the dispatch of hardware timestamps to the socket.
++ */
++static inline void skb_txtime_consumed(struct sk_buff *skb)
++{
++      skb->tstamp = ktime_set(0, 0);
++}
++
+ #endif
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-add-atomic_long_t-to-net_device_stats-fields.patch b/queue-5.10/net-add-atomic_long_t-to-net_device_stats-fields.patch
new file mode 100644 (file)
index 0000000..5d20a4b
--- /dev/null
@@ -0,0 +1,165 @@
+From 98565d53b74ba332f9ec7065c62d56893caec54e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 08:53:55 +0000
+Subject: net: add atomic_long_t to net_device_stats fields
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 6c1c5097781f563b70a81683ea6fdac21637573b ]
+
+Long standing KCSAN issues are caused by data-race around
+some dev->stats changes.
+
+Most performance critical paths already use per-cpu
+variables, or per-queue ones.
+
+It is reasonable (and more correct) to use atomic operations
+for the slow paths.
+
+This patch adds an union for each field of net_device_stats,
+so that we can convert paths that are not yet protected
+by a spinlock or a mutex.
+
+netdev_stats_to_stats64() no longer has an #if BITS_PER_LONG==64
+
+Note that the memcpy() we were using on 64bit arches
+had no provision to avoid load-tearing,
+while atomic_long_read() is providing the needed protection
+at no cost.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netdevice.h | 58 +++++++++++++++++++++++----------------
+ include/net/dst.h         |  5 ++--
+ net/core/dev.c            | 14 ++--------
+ 3 files changed, 40 insertions(+), 37 deletions(-)
+
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index ef75567efd27..b478a16ef284 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -166,31 +166,38 @@ static inline bool dev_xmit_complete(int rc)
+  *    (unsigned long) so they can be read and written atomically.
+  */
++#define NET_DEV_STAT(FIELD)                   \
++      union {                                 \
++              unsigned long FIELD;            \
++              atomic_long_t __##FIELD;        \
++      }
++
+ struct net_device_stats {
+-      unsigned long   rx_packets;
+-      unsigned long   tx_packets;
+-      unsigned long   rx_bytes;
+-      unsigned long   tx_bytes;
+-      unsigned long   rx_errors;
+-      unsigned long   tx_errors;
+-      unsigned long   rx_dropped;
+-      unsigned long   tx_dropped;
+-      unsigned long   multicast;
+-      unsigned long   collisions;
+-      unsigned long   rx_length_errors;
+-      unsigned long   rx_over_errors;
+-      unsigned long   rx_crc_errors;
+-      unsigned long   rx_frame_errors;
+-      unsigned long   rx_fifo_errors;
+-      unsigned long   rx_missed_errors;
+-      unsigned long   tx_aborted_errors;
+-      unsigned long   tx_carrier_errors;
+-      unsigned long   tx_fifo_errors;
+-      unsigned long   tx_heartbeat_errors;
+-      unsigned long   tx_window_errors;
+-      unsigned long   rx_compressed;
+-      unsigned long   tx_compressed;
++      NET_DEV_STAT(rx_packets);
++      NET_DEV_STAT(tx_packets);
++      NET_DEV_STAT(rx_bytes);
++      NET_DEV_STAT(tx_bytes);
++      NET_DEV_STAT(rx_errors);
++      NET_DEV_STAT(tx_errors);
++      NET_DEV_STAT(rx_dropped);
++      NET_DEV_STAT(tx_dropped);
++      NET_DEV_STAT(multicast);
++      NET_DEV_STAT(collisions);
++      NET_DEV_STAT(rx_length_errors);
++      NET_DEV_STAT(rx_over_errors);
++      NET_DEV_STAT(rx_crc_errors);
++      NET_DEV_STAT(rx_frame_errors);
++      NET_DEV_STAT(rx_fifo_errors);
++      NET_DEV_STAT(rx_missed_errors);
++      NET_DEV_STAT(tx_aborted_errors);
++      NET_DEV_STAT(tx_carrier_errors);
++      NET_DEV_STAT(tx_fifo_errors);
++      NET_DEV_STAT(tx_heartbeat_errors);
++      NET_DEV_STAT(tx_window_errors);
++      NET_DEV_STAT(rx_compressed);
++      NET_DEV_STAT(tx_compressed);
+ };
++#undef NET_DEV_STAT
+ #include <linux/cache.h>
+@@ -5256,4 +5263,9 @@ do {                                                             \
+ extern struct net_device *blackhole_netdev;
++/* Note: Avoid these macros in fast path, prefer per-cpu or per-queue counters. */
++#define DEV_STATS_INC(DEV, FIELD) atomic_long_inc(&(DEV)->stats.__##FIELD)
++#define DEV_STATS_ADD(DEV, FIELD, VAL)        \
++              atomic_long_add((VAL), &(DEV)->stats.__##FIELD)
++
+ #endif        /* _LINUX_NETDEVICE_H */
+diff --git a/include/net/dst.h b/include/net/dst.h
+index acd15c544cf3..ae2cf57d796b 100644
+--- a/include/net/dst.h
++++ b/include/net/dst.h
+@@ -356,9 +356,8 @@ static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
+ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
+                                struct net *net)
+ {
+-      /* TODO : stats should be SMP safe */
+-      dev->stats.rx_packets++;
+-      dev->stats.rx_bytes += skb->len;
++      DEV_STATS_INC(dev, rx_packets);
++      DEV_STATS_ADD(dev, rx_bytes, skb->len);
+       __skb_tunnel_rx(skb, dev, net);
+ }
+diff --git a/net/core/dev.c b/net/core/dev.c
+index a421c54331ea..37bb60a7e97e 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -10320,24 +10320,16 @@ void netdev_run_todo(void)
+ void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
+                            const struct net_device_stats *netdev_stats)
+ {
+-#if BITS_PER_LONG == 64
+-      BUILD_BUG_ON(sizeof(*stats64) < sizeof(*netdev_stats));
+-      memcpy(stats64, netdev_stats, sizeof(*netdev_stats));
+-      /* zero out counters that only exist in rtnl_link_stats64 */
+-      memset((char *)stats64 + sizeof(*netdev_stats), 0,
+-             sizeof(*stats64) - sizeof(*netdev_stats));
+-#else
+-      size_t i, n = sizeof(*netdev_stats) / sizeof(unsigned long);
+-      const unsigned long *src = (const unsigned long *)netdev_stats;
++      size_t i, n = sizeof(*netdev_stats) / sizeof(atomic_long_t);
++      const atomic_long_t *src = (atomic_long_t *)netdev_stats;
+       u64 *dst = (u64 *)stats64;
+       BUILD_BUG_ON(n > sizeof(*stats64) / sizeof(u64));
+       for (i = 0; i < n; i++)
+-              dst[i] = src[i];
++              dst[i] = atomic_long_read(&src[i]);
+       /* zero out counters that only exist in rtnl_link_stats64 */
+       memset((char *)stats64 + n * sizeof(u64), 0,
+              sizeof(*stats64) - n * sizeof(u64));
+-#endif
+ }
+ EXPORT_SYMBOL(netdev_stats_to_stats64);
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-add-inline-function-skb_csum_is_sctp.patch b/queue-5.10/net-add-inline-function-skb_csum_is_sctp.patch
new file mode 100644 (file)
index 0000000..75dee70
--- /dev/null
@@ -0,0 +1,71 @@
+From 90496fdb38f125ac37cf396d1e7311e275895af7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Jan 2021 14:13:37 +0800
+Subject: net: add inline function skb_csum_is_sctp
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit fa82117010430aff2ce86400f7328f55a31b48a6 ]
+
+This patch is to define a inline function skb_csum_is_sctp(), and
+also replace all places where it checks if it's a SCTP CSUM skb.
+This function would be used later in many networking drivers in
+the following patches.
+
+Suggested-by: Alexander Duyck <alexander.duyck@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: db0b124f02ba ("igc: Enhance Qbv scheduling by using first flag bit")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 2 +-
+ include/linux/skbuff.h                           | 5 +++++
+ net/core/dev.c                                   | 2 +-
+ 3 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+index 46dbb49f837c..5463c8b8e43c 100644
+--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
++++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+@@ -986,7 +986,7 @@ static int ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb)
+               stats->vlan_inserted++;
+       }
+-      if (skb->csum_not_inet)
++      if (skb_csum_is_sctp(skb))
+               stats->crc32_csum++;
+       else
+               stats->csum++;
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 521d66ec8d80..39636fe7e8f0 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -4620,6 +4620,11 @@ static inline void skb_reset_redirect(struct sk_buff *skb)
+ #endif
+ }
++static inline bool skb_csum_is_sctp(struct sk_buff *skb)
++{
++      return skb->csum_not_inet;
++}
++
+ static inline void skb_set_kcov_handle(struct sk_buff *skb,
+                                      const u64 kcov_handle)
+ {
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 34b5aab42b91..a421c54331ea 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -3631,7 +3631,7 @@ static struct sk_buff *validate_xmit_vlan(struct sk_buff *skb,
+ int skb_csum_hwoffload_help(struct sk_buff *skb,
+                           const netdev_features_t features)
+ {
+-      if (unlikely(skb->csum_not_inet))
++      if (unlikely(skb_csum_is_sctp(skb)))
+               return !!(features & NETIF_F_SCTP_CRC) ? 0 :
+                       skb_crc32c_csum_help(skb);
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-amd-lance-don-t-call-dev_kfree_skb-under-spin_lo.patch b/queue-5.10/net-amd-lance-don-t-call-dev_kfree_skb-under-spin_lo.patch
new file mode 100644 (file)
index 0000000..e285a38
--- /dev/null
@@ -0,0 +1,58 @@
+From 906acdf9bd63292825494ef555342141af3cbdbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 22:21:47 +0800
+Subject: net: amd: lance: don't call dev_kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 6151d105dfce8c23edf30eed35e97f3d9b96a35c ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+It should use dev_kfree_skb_irq() or dev_consume_skb_irq() instead.
+The difference between them is free reason, dev_kfree_skb_irq() means
+the SKB is dropped in error and dev_consume_skb_irq() means the SKB
+is consumed in normal.
+
+In these two cases, dev_kfree_skb() is called consume the xmited SKB,
+so replace it with dev_consume_skb_irq().
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/atarilance.c | 2 +-
+ drivers/net/ethernet/amd/lance.c      | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c
+index 961796abab35..5e8b72db8873 100644
+--- a/drivers/net/ethernet/amd/atarilance.c
++++ b/drivers/net/ethernet/amd/atarilance.c
+@@ -825,7 +825,7 @@ lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len );
+       head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP;
+       dev->stats.tx_bytes += skb->len;
+-      dev_kfree_skb( skb );
++      dev_consume_skb_irq(skb);
+       lp->cur_tx++;
+       while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) {
+               lp->cur_tx -= TX_RING_SIZE;
+diff --git a/drivers/net/ethernet/amd/lance.c b/drivers/net/ethernet/amd/lance.c
+index aff44241988c..9dae225b7fd5 100644
+--- a/drivers/net/ethernet/amd/lance.c
++++ b/drivers/net/ethernet/amd/lance.c
+@@ -997,7 +997,7 @@ static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
+               skb_copy_from_linear_data(skb, &lp->tx_bounce_buffs[entry], skb->len);
+               lp->tx_ring[entry].base =
+                       ((u32)isa_virt_to_bus((lp->tx_bounce_buffs + entry)) & 0xffffff) | 0x83000000;
+-              dev_kfree_skb(skb);
++              dev_consume_skb_irq(skb);
+       } else {
+               lp->tx_skbuff[entry] = skb;
+               lp->tx_ring[entry].base = ((u32)isa_virt_to_bus(skb->data) & 0xffffff) | 0x83000000;
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-amd-xgbe-check-only-the-minimum-speed-for-active.patch b/queue-5.10/net-amd-xgbe-check-only-the-minimum-speed-for-active.patch
new file mode 100644 (file)
index 0000000..d7e05db
--- /dev/null
@@ -0,0 +1,75 @@
+From e438be6cff681d2d5a5fbfac8167257e17f71653 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 10:22:25 -0600
+Subject: net: amd-xgbe: Check only the minimum speed for active/passive cables
+
+From: Tom Lendacky <thomas.lendacky@amd.com>
+
+[ Upstream commit f8ab263d4d48e6dab752029bf562f20a2ee630ed ]
+
+There are cables that exist that can support speeds in excess of 10GbE.
+The driver, however, restricts the EEPROM advertised nominal bitrate to
+a specific range, which can prevent usage of cables that can support,
+for example, up to 25GbE.
+
+Rather than checking that an active or passive cable supports a specific
+range, only check for a minimum supported speed.
+
+Fixes: abf0a1c2b26a ("amd-xgbe: Add support for SFP+ modules")
+Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+index a9a734454973..97e32c0490f8 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+@@ -237,10 +237,7 @@ enum xgbe_sfp_speed {
+ #define XGBE_SFP_BASE_BR                      12
+ #define XGBE_SFP_BASE_BR_1GBE_MIN             0x0a
+-#define XGBE_SFP_BASE_BR_1GBE_MAX             0x0d
+ #define XGBE_SFP_BASE_BR_10GBE_MIN            0x64
+-#define XGBE_SFP_BASE_BR_10GBE_MAX            0x68
+-#define XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX      0x78
+ #define XGBE_SFP_BASE_CU_CABLE_LEN            18
+@@ -827,29 +824,22 @@ static void xgbe_phy_sfp_phy_settings(struct xgbe_prv_data *pdata)
+ static bool xgbe_phy_sfp_bit_rate(struct xgbe_sfp_eeprom *sfp_eeprom,
+                                 enum xgbe_sfp_speed sfp_speed)
+ {
+-      u8 *sfp_base, min, max;
++      u8 *sfp_base, min;
+       sfp_base = sfp_eeprom->base;
+       switch (sfp_speed) {
+       case XGBE_SFP_SPEED_1000:
+               min = XGBE_SFP_BASE_BR_1GBE_MIN;
+-              max = XGBE_SFP_BASE_BR_1GBE_MAX;
+               break;
+       case XGBE_SFP_SPEED_10000:
+               min = XGBE_SFP_BASE_BR_10GBE_MIN;
+-              if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME],
+-                         XGBE_MOLEX_VENDOR, XGBE_SFP_BASE_VENDOR_NAME_LEN) == 0)
+-                      max = XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX;
+-              else
+-                      max = XGBE_SFP_BASE_BR_10GBE_MAX;
+               break;
+       default:
+               return false;
+       }
+-      return ((sfp_base[XGBE_SFP_BASE_BR] >= min) &&
+-              (sfp_base[XGBE_SFP_BASE_BR] <= max));
++      return sfp_base[XGBE_SFP_BASE_BR] >= min;
+ }
+ static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata)
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-amd-xgbe-fix-logic-around-active-and-passive-cab.patch b/queue-5.10/net-amd-xgbe-fix-logic-around-active-and-passive-cab.patch
new file mode 100644 (file)
index 0000000..f5f6032
--- /dev/null
@@ -0,0 +1,63 @@
+From 26e4cf2393cde8c2b93e23fb8d84ba1b577bf5fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 10:22:24 -0600
+Subject: net: amd-xgbe: Fix logic around active and passive cables
+
+From: Tom Lendacky <thomas.lendacky@amd.com>
+
+[ Upstream commit 4998006c73afe44e2f639d55bd331c6c26eb039f ]
+
+SFP+ active and passive cables are copper cables with fixed SFP+ end
+connectors. Due to a misinterpretation of this, SFP+ active cables could
+end up not being recognized, causing the driver to fail to establish a
+connection.
+
+Introduce a new enum in SFP+ cable types, XGBE_SFP_CABLE_FIBER, that is
+the default cable type, and handle active and passive cables when they are
+specifically detected.
+
+Fixes: abf0a1c2b26a ("amd-xgbe: Add support for SFP+ modules")
+Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+index a7166cd1179f..a9a734454973 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+@@ -189,6 +189,7 @@ enum xgbe_sfp_cable {
+       XGBE_SFP_CABLE_UNKNOWN = 0,
+       XGBE_SFP_CABLE_ACTIVE,
+       XGBE_SFP_CABLE_PASSIVE,
++      XGBE_SFP_CABLE_FIBER,
+ };
+ enum xgbe_sfp_base {
+@@ -1149,16 +1150,18 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
+       phy_data->sfp_tx_fault = xgbe_phy_check_sfp_tx_fault(phy_data);
+       phy_data->sfp_rx_los = xgbe_phy_check_sfp_rx_los(phy_data);
+-      /* Assume ACTIVE cable unless told it is PASSIVE */
++      /* Assume FIBER cable unless told otherwise */
+       if (sfp_base[XGBE_SFP_BASE_CABLE] & XGBE_SFP_BASE_CABLE_PASSIVE) {
+               phy_data->sfp_cable = XGBE_SFP_CABLE_PASSIVE;
+               phy_data->sfp_cable_len = sfp_base[XGBE_SFP_BASE_CU_CABLE_LEN];
+-      } else {
++      } else if (sfp_base[XGBE_SFP_BASE_CABLE] & XGBE_SFP_BASE_CABLE_ACTIVE) {
+               phy_data->sfp_cable = XGBE_SFP_CABLE_ACTIVE;
++      } else {
++              phy_data->sfp_cable = XGBE_SFP_CABLE_FIBER;
+       }
+       /* Determine the type of SFP */
+-      if (phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE &&
++      if (phy_data->sfp_cable != XGBE_SFP_CABLE_FIBER &&
+           xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000))
+               phy_data->sfp_base = XGBE_SFP_BASE_10000_CR;
+       else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR)
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-apple-bmac-don-t-call-dev_kfree_skb-under-spin_l.patch b/queue-5.10/net-apple-bmac-don-t-call-dev_kfree_skb-under-spin_l.patch
new file mode 100644 (file)
index 0000000..4d23dc4
--- /dev/null
@@ -0,0 +1,45 @@
+From 20332f9d65362c31c393fde80c781634d1d452e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 21:37:35 +0800
+Subject: net: apple: bmac: don't call dev_kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 5fe02e046e6422c4adfdbc50206ec7186077da24 ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+It should use dev_kfree_skb_irq() or dev_consume_skb_irq() instead.
+The difference between them is free reason, dev_kfree_skb_irq() means
+the SKB is dropped in error and dev_consume_skb_irq() means the SKB
+is consumed in normal.
+
+In this case, dev_kfree_skb() is called in bmac_tx_timeout() to drop
+the SKB, when tx timeout, so replace it with dev_kfree_skb_irq().
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/apple/bmac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c
+index 1e4e402f07d7..dd6c44f5f925 100644
+--- a/drivers/net/ethernet/apple/bmac.c
++++ b/drivers/net/ethernet/apple/bmac.c
+@@ -1511,7 +1511,7 @@ static void bmac_tx_timeout(struct timer_list *t)
+       i = bp->tx_empty;
+       ++dev->stats.tx_errors;
+       if (i != bp->tx_fill) {
+-              dev_kfree_skb(bp->tx_bufs[i]);
++              dev_kfree_skb_irq(bp->tx_bufs[i]);
+               bp->tx_bufs[i] = NULL;
+               if (++i >= N_TX_RING) i = 0;
+               bp->tx_empty = i;
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-apple-mace-don-t-call-dev_kfree_skb-under-spin_l.patch b/queue-5.10/net-apple-mace-don-t-call-dev_kfree_skb-under-spin_l.patch
new file mode 100644 (file)
index 0000000..5c695e5
--- /dev/null
@@ -0,0 +1,45 @@
+From 2a2eacd798e2da2d06ae75bc36f0e8c065a04566 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 21:37:34 +0800
+Subject: net: apple: mace: don't call dev_kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 3dfe3486c1cd4f82b466b7d307f23777137b8acc ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+It should use dev_kfree_skb_irq() or dev_consume_skb_irq() instead.
+The difference between them is free reason, dev_kfree_skb_irq() means
+the SKB is dropped in error and dev_consume_skb_irq() means the SKB
+is consumed in normal.
+
+In this case, dev_kfree_skb() is called in mace_tx_timeout() to drop
+the SKB, when tx timeout, so replace it with dev_kfree_skb_irq().
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/apple/mace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c
+index 9e5006e59215..6f6530c29166 100644
+--- a/drivers/net/ethernet/apple/mace.c
++++ b/drivers/net/ethernet/apple/mace.c
+@@ -841,7 +841,7 @@ static void mace_tx_timeout(struct timer_list *t)
+     if (mp->tx_bad_runt) {
+       mp->tx_bad_runt = 0;
+     } else if (i != mp->tx_fill) {
+-      dev_kfree_skb(mp->tx_bufs[i]);
++      dev_kfree_skb_irq(mp->tx_bufs[i]);
+       if (++i >= N_TX_RING)
+           i = 0;
+       mp->tx_empty = i;
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-defxx-fix-missing-err-handling-in-dfx_init.patch b/queue-5.10/net-defxx-fix-missing-err-handling-in-dfx_init.patch
new file mode 100644 (file)
index 0000000..f5ed70c
--- /dev/null
@@ -0,0 +1,61 @@
+From 230dedfb3a15e47f6637ed3b12ea1551cef838ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 07:20:45 +0000
+Subject: net: defxx: Fix missing err handling in dfx_init()
+
+From: Yongqiang Liu <liuyongqiang13@huawei.com>
+
+[ Upstream commit ae18dcdff0f8d7e84cd3fd9f496518b5e72d185d ]
+
+When eisa_driver_register() or tc_register_driver() failed,
+the modprobe defxx would fail with some err log as follows:
+
+ Error: Driver 'defxx' is already registered, aborting...
+
+Fix this issue by adding err hanling in dfx_init().
+
+Fixes: e89a2cfb7d7b5 ("[TC] defxx: TURBOchannel support")
+Signed-off-by: Yongqiang Liu <liuyongqiang13@huawei.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/fddi/defxx.c | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c
+index c7ce6d5491af..442bdc6e8dc4 100644
+--- a/drivers/net/fddi/defxx.c
++++ b/drivers/net/fddi/defxx.c
+@@ -3844,10 +3844,24 @@ static int dfx_init(void)
+       int status;
+       status = pci_register_driver(&dfx_pci_driver);
+-      if (!status)
+-              status = eisa_driver_register(&dfx_eisa_driver);
+-      if (!status)
+-              status = tc_register_driver(&dfx_tc_driver);
++      if (status)
++              goto err_pci_register;
++
++      status = eisa_driver_register(&dfx_eisa_driver);
++      if (status)
++              goto err_eisa_register;
++
++      status = tc_register_driver(&dfx_tc_driver);
++      if (status)
++              goto err_tc_register;
++
++      return 0;
++
++err_tc_register:
++      eisa_driver_unregister(&dfx_eisa_driver);
++err_eisa_register:
++      pci_unregister_driver(&dfx_pci_driver);
++err_pci_register:
+       return status;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-emaclite-don-t-call-dev_kfree_skb-under-spin_loc.patch b/queue-5.10/net-emaclite-don-t-call-dev_kfree_skb-under-spin_loc.patch
new file mode 100644 (file)
index 0000000..28e6939
--- /dev/null
@@ -0,0 +1,44 @@
+From 6ce75b27654cb47cafbf2241fd35a29dea1b2fde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 22:21:44 +0800
+Subject: net: emaclite: don't call dev_kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit d1678bf45f21fa5ae4a456f821858679556ea5f8 ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+It should use dev_kfree_skb_irq() or dev_consume_skb_irq() instead.
+The difference between them is free reason, dev_kfree_skb_irq() means
+the SKB is dropped in error and dev_consume_skb_irq() means the SKB
+is consumed in normal.
+
+In this case, dev_kfree_skb() is called in xemaclite_tx_timeout() to
+drop the SKB, when tx timeout, so replace it with dev_kfree_skb_irq().
+
+Fixes: bb81b2ddfa19 ("net: add Xilinx emac lite device driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+index f6ea4a0ad5df..02b95afe2506 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+@@ -541,7 +541,7 @@ static void xemaclite_tx_timeout(struct net_device *dev, unsigned int txqueue)
+       xemaclite_enable_interrupts(lp);
+       if (lp->deferred_skb) {
+-              dev_kfree_skb(lp->deferred_skb);
++              dev_kfree_skb_irq(lp->deferred_skb);
+               lp->deferred_skb = NULL;
+               dev->stats.tx_errors++;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-ethernet-dnet-don-t-call-dev_kfree_skb-under-spi.patch b/queue-5.10/net-ethernet-dnet-don-t-call-dev_kfree_skb-under-spi.patch
new file mode 100644 (file)
index 0000000..3b62ab7
--- /dev/null
@@ -0,0 +1,45 @@
+From c9c914aadc96db2df7dbe915f971d6bafde2c3ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 22:21:45 +0800
+Subject: net: ethernet: dnet: don't call dev_kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit f07fadcbee2a5e84caa67c7c445424200bffb60b ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+In this case, the lock is used to protected 'bp', so we can move
+dev_kfree_skb() after the spin_unlock_irqrestore().
+
+Fixes: 4796417417a6 ("dnet: Dave DNET ethernet controller driver (updated)")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dnet.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c
+index 48c6eb142dcc..05a0cc583f8a 100644
+--- a/drivers/net/ethernet/dnet.c
++++ b/drivers/net/ethernet/dnet.c
+@@ -550,11 +550,11 @@ static netdev_tx_t dnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       skb_tx_timestamp(skb);
++      spin_unlock_irqrestore(&bp->lock, flags);
++
+       /* free the buffer */
+       dev_kfree_skb(skb);
+-      spin_unlock_irqrestore(&bp->lock, flags);
+-
+       return NETDEV_TX_OK;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-ethernet-ti-fix-return-type-of-netcp_ndo_start_x.patch b/queue-5.10/net-ethernet-ti-fix-return-type-of-netcp_ndo_start_x.patch
new file mode 100644 (file)
index 0000000..d345631
--- /dev/null
@@ -0,0 +1,53 @@
+From 7f52530a1794068302c0c6adb6267100146ba5bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 09:09:33 -0700
+Subject: net: ethernet: ti: Fix return type of netcp_ndo_start_xmit()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 63fe6ff674a96cfcfc0fa8df1051a27aa31c70b4 ]
+
+With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
+indirect call targets are validated against the expected function
+pointer prototype to make sure the call target is valid to help mitigate
+ROP attacks. If they are not identical, there is a failure at run time,
+which manifests as either a kernel panic or thread getting killed. A
+proposed warning in clang aims to catch these at compile time, which
+reveals:
+
+  drivers/net/ethernet/ti/netcp_core.c:1944:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+          .ndo_start_xmit         = netcp_ndo_start_xmit,
+                                    ^~~~~~~~~~~~~~~~~~~~
+  1 error generated.
+
+->ndo_start_xmit() in 'struct net_device_ops' expects a return type of
+'netdev_tx_t', not 'int'. Adjust the return type of
+netcp_ndo_start_xmit() to match the prototype's to resolve the warning
+and CFI failure.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1750
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20221102160933.1601260-1-nathan@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/netcp_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c
+index dc50e948195d..f145abb77a49 100644
+--- a/drivers/net/ethernet/ti/netcp_core.c
++++ b/drivers/net/ethernet/ti/netcp_core.c
+@@ -1262,7 +1262,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp,
+ }
+ /* Submit the packet */
+-static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
++static netdev_tx_t netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ {
+       struct netcp_intf *netcp = netdev_priv(ndev);
+       struct netcp_stats *tx_stats = &netcp->stats;
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-farsync-fix-kmemleak-when-rmmods-farsync.patch b/queue-5.10/net-farsync-fix-kmemleak-when-rmmods-farsync.patch
new file mode 100644 (file)
index 0000000..3828b13
--- /dev/null
@@ -0,0 +1,75 @@
+From 5413fa43953c58d06a5bb7e42abe3c44b4de9164 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 20:05:40 +0800
+Subject: net: farsync: Fix kmemleak when rmmods farsync
+
+From: Li Zetao <lizetao1@huawei.com>
+
+[ Upstream commit 2f623aaf9f31de968dea6169849706a2f9be444c ]
+
+There are two memory leaks reported by kmemleak:
+
+  unreferenced object 0xffff888114b20200 (size 128):
+    comm "modprobe", pid 4846, jiffies 4295146524 (age 401.345s)
+    hex dump (first 32 bytes):
+      e0 62 57 09 81 88 ff ff e0 62 57 09 81 88 ff ff  .bW......bW.....
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    backtrace:
+      [<ffffffff815bcd82>] kmalloc_trace+0x22/0x60
+      [<ffffffff83d35c78>] __hw_addr_add_ex+0x198/0x6c0
+      [<ffffffff83d3989d>] dev_addr_init+0x13d/0x230
+      [<ffffffff83d1063d>] alloc_netdev_mqs+0x10d/0xe50
+      [<ffffffff82b4a06e>] alloc_hdlcdev+0x2e/0x80
+      [<ffffffffa016a741>] fst_add_one+0x601/0x10e0 [farsync]
+      ...
+
+  unreferenced object 0xffff88810b85b000 (size 1024):
+    comm "modprobe", pid 4846, jiffies 4295146523 (age 401.346s)
+    hex dump (first 32 bytes):
+      00 00 b0 02 00 c9 ff ff 00 70 0a 00 00 c9 ff ff  .........p......
+      00 00 00 f2 00 00 00 f3 0a 00 00 00 02 00 00 00  ................
+    backtrace:
+      [<ffffffff815bcd82>] kmalloc_trace+0x22/0x60
+      [<ffffffffa016a294>] fst_add_one+0x154/0x10e0 [farsync]
+      [<ffffffff82060e83>] local_pci_probe+0xd3/0x170
+      ...
+
+The root cause is traced to the netdev and fst_card_info are not freed
+when removes one fst in fst_remove_one(), which may trigger oom if
+repeated insmod and rmmod module.
+
+Fix it by adding free_netdev() and kfree() in fst_remove_one(), just as
+the operations on the error handling path in fst_add_one().
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wan/farsync.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
+index b50cf11d197d..36a6958b6a0b 100644
+--- a/drivers/net/wan/farsync.c
++++ b/drivers/net/wan/farsync.c
+@@ -2612,6 +2612,7 @@ fst_remove_one(struct pci_dev *pdev)
+       for (i = 0; i < card->nports; i++) {
+               struct net_device *dev = port_to_dev(&card->ports[i]);
+               unregister_hdlc_device(dev);
++              free_netdev(dev);
+       }
+       fst_disable_intr(card);
+@@ -2632,6 +2633,7 @@ fst_remove_one(struct pci_dev *pdev)
+                                 card->tx_dma_handle_card);
+       }
+       fst_card_array[card->card_no] = NULL;
++      kfree(card);
+ }
+ static struct pci_driver fst_driver = {
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-hsr-generate-supervision-frame-without-hsr-prp-t.patch b/queue-5.10/net-hsr-generate-supervision-frame-without-hsr-prp-t.patch
new file mode 100644 (file)
index 0000000..f627fea
--- /dev/null
@@ -0,0 +1,189 @@
+From 405bfcf701bf2409066578f13361115964fb12ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Feb 2021 19:02:10 -0600
+Subject: net: hsr: generate supervision frame without HSR/PRP tag
+
+From: George McCollister <george.mccollister@gmail.com>
+
+[ Upstream commit 78be9217c4014cebac4d549cc2db1f2886d5a8fb ]
+
+For a switch to offload insertion of HSR/PRP tags, frames must not be
+sent to the CPU facing switch port with a tag. Generate supervision frames
+(eth type ETH_P_PRP) without HSR v1 (ETH_P_HSR)/PRP tag and rely on
+create_tagged_frame which inserts it later. This will allow skipping the
+tag insertion for all outgoing frames in the future which is required for
+HSR v1/PRP tag insertions to be offloaded.
+
+HSR v0 supervision frames always contain tag information so insertion of
+the tag can't be offloaded. IEC 62439-3 Ed.2.0 (HSR v1) specifically
+notes that this was changed since v0 to allow offloading.
+
+Signed-off-by: George McCollister <george.mccollister@gmail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Tested-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: d5c7652eb16f ("hsr: Disable netpoll.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_device.c  | 39 +++++++--------------------------------
+ net/hsr/hsr_forward.c |  8 +++++++-
+ 2 files changed, 14 insertions(+), 33 deletions(-)
+
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index fec1b014c0a2..7449c3c95317 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -232,7 +232,7 @@ static const struct header_ops hsr_header_ops = {
+       .parse   = eth_header_parse,
+ };
+-static struct sk_buff *hsr_init_skb(struct hsr_port *master, u16 proto)
++static struct sk_buff *hsr_init_skb(struct hsr_port *master)
+ {
+       struct hsr_priv *hsr = master->hsr;
+       struct sk_buff *skb;
+@@ -244,8 +244,7 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master, u16 proto)
+        * being, for PRP it is a trailer and for HSR it is a
+        * header
+        */
+-      skb = dev_alloc_skb(sizeof(struct hsr_tag) +
+-                          sizeof(struct hsr_sup_tag) +
++      skb = dev_alloc_skb(sizeof(struct hsr_sup_tag) +
+                           sizeof(struct hsr_sup_payload) + hlen + tlen);
+       if (!skb)
+@@ -253,10 +252,9 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master, u16 proto)
+       skb_reserve(skb, hlen);
+       skb->dev = master->dev;
+-      skb->protocol = htons(proto);
+       skb->priority = TC_PRIO_CONTROL;
+-      if (dev_hard_header(skb, skb->dev, proto,
++      if (dev_hard_header(skb, skb->dev, ETH_P_PRP,
+                           hsr->sup_multicast_addr,
+                           skb->dev->dev_addr, skb->len) <= 0)
+               goto out;
+@@ -278,12 +276,10 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+ {
+       struct hsr_priv *hsr = master->hsr;
+       __u8 type = HSR_TLV_LIFE_CHECK;
+-      struct hsr_tag *hsr_tag = NULL;
+       struct hsr_sup_payload *hsr_sp;
+       struct hsr_sup_tag *hsr_stag;
+       unsigned long irqflags;
+       struct sk_buff *skb;
+-      u16 proto;
+       *interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL);
+       if (hsr->announce_count < 3 && hsr->prot_version == 0) {
+@@ -292,23 +288,12 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+               hsr->announce_count++;
+       }
+-      if (!hsr->prot_version)
+-              proto = ETH_P_PRP;
+-      else
+-              proto = ETH_P_HSR;
+-
+-      skb = hsr_init_skb(master, proto);
++      skb = hsr_init_skb(master);
+       if (!skb) {
+               WARN_ONCE(1, "HSR: Could not send supervision frame\n");
+               return;
+       }
+-      if (hsr->prot_version > 0) {
+-              hsr_tag = skb_put(skb, sizeof(struct hsr_tag));
+-              hsr_tag->encap_proto = htons(ETH_P_PRP);
+-              set_hsr_tag_LSDU_size(hsr_tag, HSR_V1_SUP_LSDUSIZE);
+-      }
+-
+       hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag));
+       set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf));
+       set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version);
+@@ -318,8 +303,6 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+       if (hsr->prot_version > 0) {
+               hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr);
+               hsr->sup_sequence_nr++;
+-              hsr_tag->sequence_nr = htons(hsr->sequence_nr);
+-              hsr->sequence_nr++;
+       } else {
+               hsr_stag->sequence_nr = htons(hsr->sequence_nr);
+               hsr->sequence_nr++;
+@@ -335,7 +318,7 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+       hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
+       ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
+-      if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN))
++      if (skb_put_padto(skb, ETH_ZLEN))
+               return;
+       hsr_forward_skb(skb, master);
+@@ -351,10 +334,8 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+       struct hsr_sup_tag *hsr_stag;
+       unsigned long irqflags;
+       struct sk_buff *skb;
+-      struct prp_rct *rct;
+-      u8 *tail;
+-      skb = hsr_init_skb(master, ETH_P_PRP);
++      skb = hsr_init_skb(master);
+       if (!skb) {
+               WARN_ONCE(1, "PRP: Could not send supervision frame\n");
+               return;
+@@ -376,17 +357,11 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+       hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
+       ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
+-      if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN)) {
++      if (skb_put_padto(skb, ETH_ZLEN)) {
+               spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
+               return;
+       }
+-      tail = skb_tail_pointer(skb) - HSR_HLEN;
+-      rct = (struct prp_rct *)tail;
+-      rct->PRP_suffix = htons(ETH_P_PRP);
+-      set_prp_LSDU_size(rct, HSR_V1_SUP_LSDUSIZE);
+-      rct->sequence_nr = htons(hsr->sequence_nr);
+-      hsr->sequence_nr++;
+       spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
+       hsr_forward_skb(skb, master);
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index 90b0ed16552b..15653d3bb6ac 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -186,6 +186,7 @@ static struct sk_buff *prp_fill_rct(struct sk_buff *skb,
+       set_prp_LSDU_size(trailer, lsdu_size);
+       trailer->sequence_nr = htons(frame->sequence_nr);
+       trailer->PRP_suffix = htons(ETH_P_PRP);
++      skb->protocol = eth_hdr(skb)->h_proto;
+       return skb;
+ }
+@@ -226,6 +227,7 @@ static struct sk_buff *hsr_fill_tag(struct sk_buff *skb,
+       hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto;
+       hsr_ethhdr->ethhdr.h_proto = htons(proto_version ?
+                       ETH_P_HSR : ETH_P_PRP);
++      skb->protocol = hsr_ethhdr->ethhdr.h_proto;
+       return skb;
+ }
+@@ -455,7 +457,11 @@ static void handle_std_frame(struct sk_buff *skb,
+ int hsr_fill_frame_info(__be16 proto, struct sk_buff *skb,
+                       struct hsr_frame_info *frame)
+ {
+-      if (proto == htons(ETH_P_PRP) ||
++      struct hsr_port *port = frame->port_rcv;
++      struct hsr_priv *hsr = port->hsr;
++
++      /* HSRv0 supervisory frames double as a tag so treat them as tagged. */
++      if ((!hsr->prot_version && proto == htons(ETH_P_PRP)) ||
+           proto == htons(ETH_P_HSR)) {
+               /* Check if skb contains hsr_ethhdr */
+               if (skb->mac_len < sizeof(struct hsr_ethhdr))
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-igc-use-skb_csum_is_sctp-instead-of-protocol-che.patch b/queue-5.10/net-igc-use-skb_csum_is_sctp-instead-of-protocol-che.patch
new file mode 100644 (file)
index 0000000..8c4ade4
--- /dev/null
@@ -0,0 +1,58 @@
+From 057846c2684fae441370e074d2c54e8e283f7e8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Jan 2021 14:13:40 +0800
+Subject: net: igc: use skb_csum_is_sctp instead of protocol check
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 609d29a9d2429a840a2f1f44e77b71d58e3e9a33 ]
+
+Using skb_csum_is_sctp is a easier way to validate it's a SCTP CRC
+checksum offload packet, and yet it also makes igc support SCTP
+CRC checksum offload for UDP and GRE encapped packets, just as it
+does in igb driver.
+
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: db0b124f02ba ("igc: Enhance Qbv scheduling by using first flag bit")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_main.c | 14 +-------------
+ 1 file changed, 1 insertion(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index e7ffe63925fd..f438cdf83e55 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -954,15 +954,6 @@ static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
+       }
+ }
+-static inline bool igc_ipv6_csum_is_sctp(struct sk_buff *skb)
+-{
+-      unsigned int offset = 0;
+-
+-      ipv6_find_hdr(skb, &offset, IPPROTO_SCTP, NULL, NULL);
+-
+-      return offset == skb_checksum_start_offset(skb);
+-}
+-
+ static void igc_tx_csum(struct igc_ring *tx_ring, struct igc_tx_buffer *first)
+ {
+       struct sk_buff *skb = first->skb;
+@@ -985,10 +976,7 @@ static void igc_tx_csum(struct igc_ring *tx_ring, struct igc_tx_buffer *first)
+               break;
+       case offsetof(struct sctphdr, checksum):
+               /* validate that this is actually an SCTP request */
+-              if ((first->protocol == htons(ETH_P_IP) &&
+-                   (ip_hdr(skb)->protocol == IPPROTO_SCTP)) ||
+-                  (first->protocol == htons(ETH_P_IPV6) &&
+-                   igc_ipv6_csum_is_sctp(skb))) {
++              if (skb_csum_is_sctp(skb)) {
+                       type_tucmd = IGC_ADVTXD_TUCMD_L4T_SCTP;
+                       break;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-lan9303-fix-read-error-execution-path.patch b/queue-5.10/net-lan9303-fix-read-error-execution-path.patch
new file mode 100644 (file)
index 0000000..c4559a1
--- /dev/null
@@ -0,0 +1,44 @@
+From cd3ad9ad4abbca943897c690f8417da0fbb120ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 09:35:02 -0600
+Subject: net: lan9303: Fix read error execution path
+
+From: Jerry Ray <jerry.ray@microchip.com>
+
+[ Upstream commit 8964916d206071b058c6351f88b1966bd58cbde0 ]
+
+This patch fixes an issue where a read failure of a port statistic counter
+will return unknown results.  While it is highly unlikely the read will
+ever fail, it is much cleaner to return a zero for the stat count.
+
+Fixes: a1292595e006 ("net: dsa: add new DSA switch driver for the SMSC-LAN9303")
+Signed-off-by: Jerry Ray <jerry.ray@microchip.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Link: https://lore.kernel.org/r/20221209153502.7429-1-jerry.ray@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/lan9303-core.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
+index c79bb8cf962c..deeed50a42c0 100644
+--- a/drivers/net/dsa/lan9303-core.c
++++ b/drivers/net/dsa/lan9303-core.c
+@@ -1002,9 +1002,11 @@ static void lan9303_get_ethtool_stats(struct dsa_switch *ds, int port,
+               ret = lan9303_read_switch_port(
+                       chip, port, lan9303_mib[u].offset, &reg);
+-              if (ret)
++              if (ret) {
+                       dev_warn(chip->dev, "Reading status port %d reg %u failed\n",
+                                port, lan9303_mib[u].offset);
++                      reg = 0;
++              }
+               data[u] = reg;
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-macsec-fix-net-device-access-prior-to-holding-a-.patch b/queue-5.10/net-macsec-fix-net-device-access-prior-to-holding-a-.patch
new file mode 100644 (file)
index 0000000..15b2d6b
--- /dev/null
@@ -0,0 +1,96 @@
+From bef73f594170658c6e7e243493aa4a894692b33b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Dec 2022 09:55:32 +0200
+Subject: net: macsec: fix net device access prior to holding a lock
+
+From: Emeel Hakim <ehakim@nvidia.com>
+
+[ Upstream commit f3b4a00f0f62da252c598310698dfc82ef2f2e2e ]
+
+Currently macsec offload selection update routine accesses
+the net device prior to holding the relevant lock.
+Fix by holding the lock prior to the device access.
+
+Fixes: dcb780fb2795 ("net: macsec: add nla support for changing the offloading selection")
+Reviewed-by: Raed Salem <raeds@nvidia.com>
+Signed-off-by: Emeel Hakim <ehakim@nvidia.com>
+Link: https://lore.kernel.org/r/20221211075532.28099-1-ehakim@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macsec.c | 34 +++++++++++++++++++++-------------
+ 1 file changed, 21 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index eb029456b594..4fdb970e3482 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -2584,7 +2584,7 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+       const struct macsec_ops *ops;
+       struct macsec_context ctx;
+       struct macsec_dev *macsec;
+-      int ret;
++      int ret = 0;
+       if (!attrs[MACSEC_ATTR_IFINDEX])
+               return -EINVAL;
+@@ -2597,28 +2597,36 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+                                       macsec_genl_offload_policy, NULL))
+               return -EINVAL;
++      rtnl_lock();
++
+       dev = get_dev_from_nl(genl_info_net(info), attrs);
+-      if (IS_ERR(dev))
+-              return PTR_ERR(dev);
++      if (IS_ERR(dev)) {
++              ret = PTR_ERR(dev);
++              goto out;
++      }
+       macsec = macsec_priv(dev);
+-      if (!tb_offload[MACSEC_OFFLOAD_ATTR_TYPE])
+-              return -EINVAL;
++      if (!tb_offload[MACSEC_OFFLOAD_ATTR_TYPE]) {
++              ret = -EINVAL;
++              goto out;
++      }
+       offload = nla_get_u8(tb_offload[MACSEC_OFFLOAD_ATTR_TYPE]);
+       if (macsec->offload == offload)
+-              return 0;
++              goto out;
+       /* Check if the offloading mode is supported by the underlying layers */
+       if (offload != MACSEC_OFFLOAD_OFF &&
+-          !macsec_check_offload(offload, macsec))
+-              return -EOPNOTSUPP;
++          !macsec_check_offload(offload, macsec)) {
++              ret = -EOPNOTSUPP;
++              goto out;
++      }
+       /* Check if the net device is busy. */
+-      if (netif_running(dev))
+-              return -EBUSY;
+-
+-      rtnl_lock();
++      if (netif_running(dev)) {
++              ret = -EBUSY;
++              goto out;
++      }
+       prev_offload = macsec->offload;
+       macsec->offload = offload;
+@@ -2653,7 +2661,7 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+ rollback:
+       macsec->offload = prev_offload;
+-
++out:
+       rtnl_unlock();
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-proc-provide-proc_fs-n-fallback-for-proc_create_.patch b/queue-5.10/net-proc-provide-proc_fs-n-fallback-for-proc_create_.patch
new file mode 100644 (file)
index 0000000..1cae070
--- /dev/null
@@ -0,0 +1,43 @@
+From 96617d95b1b3a9a06d4f39b9836aacb9e2347a2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Oct 2022 07:34:21 +0100
+Subject: net, proc: Provide PROC_FS=n fallback for
+ proc_create_net_single_write()
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit c3d96f690a790074b508fe183a41e36a00cd7ddd ]
+
+Provide a CONFIG_PROC_FS=n fallback for proc_create_net_single_write().
+
+Also provide a fallback for proc_create_net_data_write().
+
+Fixes: 564def71765c ("proc: Add a way to make network proc files writable")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+cc: netdev@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/proc_fs.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
+index 000cc0533c33..8c892730a1f1 100644
+--- a/include/linux/proc_fs.h
++++ b/include/linux/proc_fs.h
+@@ -190,8 +190,10 @@ static inline void proc_remove(struct proc_dir_entry *de) {}
+ static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) { return 0; }
+ #define proc_create_net_data(name, mode, parent, ops, state_size, data) ({NULL;})
++#define proc_create_net_data_write(name, mode, parent, ops, write, state_size, data) ({NULL;})
+ #define proc_create_net(name, mode, parent, state_size, ops) ({NULL;})
+ #define proc_create_net_single(name, mode, parent, show, data) ({NULL;})
++#define proc_create_net_single_write(name, mode, parent, show, write, data) ({NULL;})
+ static inline struct pid *tgid_pidfd_to_pid(const struct file *file)
+ {
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-stmmac-selftests-fix-potential-memleak-in-stmmac.patch b/queue-5.10/net-stmmac-selftests-fix-potential-memleak-in-stmmac.patch
new file mode 100644 (file)
index 0000000..787a23c
--- /dev/null
@@ -0,0 +1,50 @@
+From fc4bcd23d7c7c29b8f889c3377b724bb9f43ee4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 16:31:59 +0800
+Subject: net: stmmac: selftests: fix potential memleak in
+ stmmac_test_arpoffload()
+
+From: Zhang Changzhong <zhangchangzhong@huawei.com>
+
+[ Upstream commit f150b63f3fa5fdd81e0dd6151e8850268e29438c ]
+
+The skb allocated by stmmac_test_get_arp_skb() hasn't been released in
+some error handling case, which will lead to a memory leak. Fix this up
+by adding kfree_skb() to release skb.
+
+Compile tested only.
+
+Fixes: 5e3fb0a6e2b3 ("net: stmmac: selftests: Implement the ARP Offload test")
+Signed-off-by: Zhang Changzhong <zhangchangzhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+index dd5c4ef92ef3..ea7200b7b647 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+@@ -1654,12 +1654,16 @@ static int stmmac_test_arpoffload(struct stmmac_priv *priv)
+       }
+       ret = stmmac_set_arp_offload(priv, priv->hw, true, ip_addr);
+-      if (ret)
++      if (ret) {
++              kfree_skb(skb);
+               goto cleanup;
++      }
+       ret = dev_set_promiscuity(priv->dev, 1);
+-      if (ret)
++      if (ret) {
++              kfree_skb(skb);
+               goto cleanup;
++      }
+       ret = dev_direct_xmit(skb, 0);
+       if (ret)
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-stream-purge-sk_error_queue-in-sk_stream_kill_qu.patch b/queue-5.10/net-stream-purge-sk_error_queue-in-sk_stream_kill_qu.patch
new file mode 100644 (file)
index 0000000..8b9c0a8
--- /dev/null
@@ -0,0 +1,69 @@
+From 4f6352c5c3ef6ca33f1d4ea735b93dda1728e7dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Dec 2022 16:29:17 +0000
+Subject: net: stream: purge sk_error_queue in sk_stream_kill_queues()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit e0c8bccd40fc1c19e1d246c39bcf79e357e1ada3 ]
+
+Changheon Lee reported TCP socket leaks, with a nice repro.
+
+It seems we leak TCP sockets with the following sequence:
+
+1) SOF_TIMESTAMPING_TX_ACK is enabled on the socket.
+
+   Each ACK will cook an skb put in error queue, from __skb_tstamp_tx().
+   __skb_tstamp_tx() is using skb_clone(), unless
+   SOF_TIMESTAMPING_OPT_TSONLY was also requested.
+
+2) If the application is also using MSG_ZEROCOPY, then we put in the
+   error queue cloned skbs that had a struct ubuf_info attached to them.
+
+   Whenever an struct ubuf_info is allocated, sock_zerocopy_alloc()
+   does a sock_hold().
+
+   As long as the cloned skbs are still in sk_error_queue,
+   socket refcount is kept elevated.
+
+3) Application closes the socket, while error queue is not empty.
+
+Since tcp_close() no longer purges the socket error queue,
+we might end up with a TCP socket with at least one skb in
+error queue keeping the socket alive forever.
+
+This bug can be (ab)used to consume all kernel memory
+and freeze the host.
+
+We need to purge the error queue, with proper synchronization
+against concurrent writers.
+
+Fixes: 24bcbe1cc69f ("net: stream: don't purge sk_error_queue in sk_stream_kill_queues()")
+Reported-by: Changheon Lee <darklight2357@icloud.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/stream.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/core/stream.c b/net/core/stream.c
+index a61130504827..d7c5413d16d5 100644
+--- a/net/core/stream.c
++++ b/net/core/stream.c
+@@ -196,6 +196,12 @@ void sk_stream_kill_queues(struct sock *sk)
+       /* First the read buffer. */
+       __skb_queue_purge(&sk->sk_receive_queue);
++      /* Next, the error queue.
++       * We need to use queue lock, because other threads might
++       * add packets to the queue without socket lock being held.
++       */
++      skb_queue_purge(&sk->sk_error_queue);
++
+       /* Next, the write queue. */
+       WARN_ON(!skb_queue_empty(&sk->sk_write_queue));
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-switch-to-storing-kcov-handle-directly-in-sk_buf.patch b/queue-5.10/net-switch-to-storing-kcov-handle-directly-in-sk_buf.patch
new file mode 100644 (file)
index 0000000..e7ecc85
--- /dev/null
@@ -0,0 +1,148 @@
+From 952fd23b1f8d53b5ed86e9e8948e56e091098d4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Nov 2020 23:48:40 +0100
+Subject: net: switch to storing KCOV handle directly in sk_buff
+
+From: Marco Elver <elver@google.com>
+
+[ Upstream commit fa69ee5aa48b5b52e8028c2eb486906e9998d081 ]
+
+It turns out that usage of skb extensions can cause memory leaks. Ido
+Schimmel reported: "[...] there are instances that blindly overwrite
+'skb->extensions' by invoking skb_copy_header() after __alloc_skb()."
+
+Therefore, give up on using skb extensions for KCOV handle, and instead
+directly store kcov_handle in sk_buff.
+
+Fixes: 6370cc3bbd8a ("net: add kcov handle to skb extensions")
+Fixes: 85ce50d337d1 ("net: kcov: don't select SKB_EXTENSIONS when there is no NET")
+Fixes: 97f53a08cba1 ("net: linux/skbuff.h: combine SKB_EXTENSIONS + KCOV handling")
+Link: https://lore.kernel.org/linux-wireless/20201121160941.GA485907@shredder.lan/
+Reported-by: Ido Schimmel <idosch@idosch.org>
+Signed-off-by: Marco Elver <elver@google.com>
+Link: https://lore.kernel.org/r/20201125224840.2014773-1-elver@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: db0b124f02ba ("igc: Enhance Qbv scheduling by using first flag bit")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/skbuff.h | 37 +++++++++++++------------------------
+ lib/Kconfig.debug      |  1 -
+ net/core/skbuff.c      |  6 ------
+ 3 files changed, 13 insertions(+), 31 deletions(-)
+
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 462b0e3ef2b2..521d66ec8d80 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -702,6 +702,7 @@ typedef unsigned char *sk_buff_data_t;
+  *    @transport_header: Transport layer header
+  *    @network_header: Network layer header
+  *    @mac_header: Link layer header
++ *    @kcov_handle: KCOV remote handle for remote coverage collection
+  *    @tail: Tail pointer
+  *    @end: End pointer
+  *    @head: Head of buffer
+@@ -906,6 +907,10 @@ struct sk_buff {
+       __u16                   network_header;
+       __u16                   mac_header;
++#ifdef CONFIG_KCOV
++      u64                     kcov_handle;
++#endif
++
+       /* private: */
+       __u32                   headers_end[0];
+       /* public: */
+@@ -4160,9 +4165,6 @@ enum skb_ext_id {
+ #endif
+ #if IS_ENABLED(CONFIG_MPTCP)
+       SKB_EXT_MPTCP,
+-#endif
+-#if IS_ENABLED(CONFIG_KCOV)
+-      SKB_EXT_KCOV_HANDLE,
+ #endif
+       SKB_EXT_NUM, /* must be last */
+ };
+@@ -4618,35 +4620,22 @@ static inline void skb_reset_redirect(struct sk_buff *skb)
+ #endif
+ }
+-#if IS_ENABLED(CONFIG_KCOV) && IS_ENABLED(CONFIG_SKB_EXTENSIONS)
+ static inline void skb_set_kcov_handle(struct sk_buff *skb,
+                                      const u64 kcov_handle)
+ {
+-      /* Do not allocate skb extensions only to set kcov_handle to zero
+-       * (as it is zero by default). However, if the extensions are
+-       * already allocated, update kcov_handle anyway since
+-       * skb_set_kcov_handle can be called to zero a previously set
+-       * value.
+-       */
+-      if (skb_has_extensions(skb) || kcov_handle) {
+-              u64 *kcov_handle_ptr = skb_ext_add(skb, SKB_EXT_KCOV_HANDLE);
+-
+-              if (kcov_handle_ptr)
+-                      *kcov_handle_ptr = kcov_handle;
+-      }
++#ifdef CONFIG_KCOV
++      skb->kcov_handle = kcov_handle;
++#endif
+ }
+ static inline u64 skb_get_kcov_handle(struct sk_buff *skb)
+ {
+-      u64 *kcov_handle = skb_ext_find(skb, SKB_EXT_KCOV_HANDLE);
+-
+-      return kcov_handle ? *kcov_handle : 0;
+-}
++#ifdef CONFIG_KCOV
++      return skb->kcov_handle;
+ #else
+-static inline void skb_set_kcov_handle(struct sk_buff *skb,
+-                                     const u64 kcov_handle) { }
+-static inline u64 skb_get_kcov_handle(struct sk_buff *skb) { return 0; }
+-#endif /* CONFIG_KCOV && CONFIG_SKB_EXTENSIONS */
++      return 0;
++#endif
++}
+ #endif        /* __KERNEL__ */
+ #endif        /* _LINUX_SKBUFF_H */
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 4aed8abb2022..19c28a34c5f1 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -1915,7 +1915,6 @@ config KCOV
+       depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS
+       select DEBUG_FS
+       select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC
+-      select SKB_EXTENSIONS if NET
+       help
+         KCOV exposes kernel code coverage information in a form suitable
+         for coverage-guided fuzzing (randomized testing).
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 06169889b0ca..176bcbb07aab 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -4258,9 +4258,6 @@ static const u8 skb_ext_type_len[] = {
+ #if IS_ENABLED(CONFIG_MPTCP)
+       [SKB_EXT_MPTCP] = SKB_EXT_CHUNKSIZEOF(struct mptcp_ext),
+ #endif
+-#if IS_ENABLED(CONFIG_KCOV)
+-      [SKB_EXT_KCOV_HANDLE] = SKB_EXT_CHUNKSIZEOF(u64),
+-#endif
+ };
+ static __always_inline unsigned int skb_ext_total_length(void)
+@@ -4277,9 +4274,6 @@ static __always_inline unsigned int skb_ext_total_length(void)
+ #endif
+ #if IS_ENABLED(CONFIG_MPTCP)
+               skb_ext_type_len[SKB_EXT_MPTCP] +
+-#endif
+-#if IS_ENABLED(CONFIG_KCOV)
+-              skb_ext_type_len[SKB_EXT_KCOV_HANDLE] +
+ #endif
+               0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-tunnel-wait-until-all-sk_user_data-reader-finish.patch b/queue-5.10/net-tunnel-wait-until-all-sk_user_data-reader-finish.patch
new file mode 100644 (file)
index 0000000..47cb4fe
--- /dev/null
@@ -0,0 +1,75 @@
+From 383513170076d45fc4b4c42ca400121bd34cdac9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 20:04:52 +0800
+Subject: net/tunnel: wait until all sk_user_data reader finish before
+ releasing the sock
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit 3cf7203ca620682165706f70a1b12b5194607dce ]
+
+There is a race condition in vxlan that when deleting a vxlan device
+during receiving packets, there is a possibility that the sock is
+released after getting vxlan_sock vs from sk_user_data. Then in
+later vxlan_ecn_decapsulate(), vxlan_get_sk_family() we will got
+NULL pointer dereference. e.g.
+
+   #0 [ffffa25ec6978a38] machine_kexec at ffffffff8c669757
+   #1 [ffffa25ec6978a90] __crash_kexec at ffffffff8c7c0a4d
+   #2 [ffffa25ec6978b58] crash_kexec at ffffffff8c7c1c48
+   #3 [ffffa25ec6978b60] oops_end at ffffffff8c627f2b
+   #4 [ffffa25ec6978b80] page_fault_oops at ffffffff8c678fcb
+   #5 [ffffa25ec6978bd8] exc_page_fault at ffffffff8d109542
+   #6 [ffffa25ec6978c00] asm_exc_page_fault at ffffffff8d200b62
+      [exception RIP: vxlan_ecn_decapsulate+0x3b]
+      RIP: ffffffffc1014e7b  RSP: ffffa25ec6978cb0  RFLAGS: 00010246
+      RAX: 0000000000000008  RBX: ffff8aa000888000  RCX: 0000000000000000
+      RDX: 000000000000000e  RSI: ffff8a9fc7ab803e  RDI: ffff8a9fd1168700
+      RBP: ffff8a9fc7ab803e   R8: 0000000000700000   R9: 00000000000010ae
+      R10: ffff8a9fcb748980  R11: 0000000000000000  R12: ffff8a9fd1168700
+      R13: ffff8aa000888000  R14: 00000000002a0000  R15: 00000000000010ae
+      ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
+   #7 [ffffa25ec6978ce8] vxlan_rcv at ffffffffc10189cd [vxlan]
+   #8 [ffffa25ec6978d90] udp_queue_rcv_one_skb at ffffffff8cfb6507
+   #9 [ffffa25ec6978dc0] udp_unicast_rcv_skb at ffffffff8cfb6e45
+  #10 [ffffa25ec6978dc8] __udp4_lib_rcv at ffffffff8cfb8807
+  #11 [ffffa25ec6978e20] ip_protocol_deliver_rcu at ffffffff8cf76951
+  #12 [ffffa25ec6978e48] ip_local_deliver at ffffffff8cf76bde
+  #13 [ffffa25ec6978ea0] __netif_receive_skb_one_core at ffffffff8cecde9b
+  #14 [ffffa25ec6978ec8] process_backlog at ffffffff8cece139
+  #15 [ffffa25ec6978f00] __napi_poll at ffffffff8ceced1a
+  #16 [ffffa25ec6978f28] net_rx_action at ffffffff8cecf1f3
+  #17 [ffffa25ec6978fa0] __softirqentry_text_start at ffffffff8d4000ca
+  #18 [ffffa25ec6978ff0] do_softirq at ffffffff8c6fbdc3
+
+Reproducer: https://github.com/Mellanox/ovs-tests/blob/master/test-ovs-vxlan-remove-tunnel-during-traffic.sh
+
+Fix this by waiting for all sk_user_data reader to finish before
+releasing the sock.
+
+Reported-by: Jianlin Shi <jishi@redhat.com>
+Suggested-by: Jakub Sitnicki <jakub@cloudflare.com>
+Fixes: 6a93cc905274 ("udp-tunnel: Add a few more UDP tunnel APIs")
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp_tunnel_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c
+index 3eecba0874aa..d70f683d3c49 100644
+--- a/net/ipv4/udp_tunnel_core.c
++++ b/net/ipv4/udp_tunnel_core.c
+@@ -194,6 +194,7 @@ EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb);
+ void udp_tunnel_sock_release(struct socket *sock)
+ {
+       rcu_assign_sk_user_data(sock->sk, NULL);
++      synchronize_rcu();
+       kernel_sock_shutdown(sock, SHUT_RDWR);
+       sock_release(sock);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/net-vmw_vsock-vmci-check-memcpy_from_msg.patch b/queue-5.10/net-vmw_vsock-vmci-check-memcpy_from_msg.patch
new file mode 100644 (file)
index 0000000..ce3639d
--- /dev/null
@@ -0,0 +1,47 @@
+From ce5a341e1d7ad3322140e1de602f2fdbd500d366 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 09:58:34 +0300
+Subject: net: vmw_vsock: vmci: Check memcpy_from_msg()
+
+From: Artem Chernyshev <artem.chernyshev@red-soft.ru>
+
+[ Upstream commit 44aa5a6dba8283bfda28b1517af4de711c5652a4 ]
+
+vmci_transport_dgram_enqueue() does not check the return value
+of memcpy_from_msg().  If memcpy_from_msg() fails, it is possible that
+uninitialized memory contents are sent unintentionally instead of user's
+message in the datagram to the destination.  Return with an error if
+memcpy_from_msg() fails.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 0f7db23a07af ("vmci_transport: switch ->enqeue_dgram, ->enqueue_stream and ->dequeue_stream to msghdr")
+Signed-off-by: Artem Chernyshev <artem.chernyshev@red-soft.ru>
+Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
+Reviewed-by: Vishnu Dasa <vdasa@vmware.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/vmw_vsock/vmci_transport.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
+index a9ca95a0fcdd..8c2856cbfecc 100644
+--- a/net/vmw_vsock/vmci_transport.c
++++ b/net/vmw_vsock/vmci_transport.c
+@@ -1713,7 +1713,11 @@ static int vmci_transport_dgram_enqueue(
+       if (!dg)
+               return -ENOMEM;
+-      memcpy_from_msg(VMCI_DG_PAYLOAD(dg), msg, len);
++      err = memcpy_from_msg(VMCI_DG_PAYLOAD(dg), msg, len);
++      if (err) {
++              kfree(dg);
++              return err;
++      }
+       dg->dst = vmci_make_handle(remote_addr->svm_cid,
+                                  remote_addr->svm_port);
+-- 
+2.35.1
+
diff --git a/queue-5.10/net_sched-reject-tcf_em_simple-case-for-complex-emat.patch b/queue-5.10/net_sched-reject-tcf_em_simple-case-for-complex-emat.patch
new file mode 100644 (file)
index 0000000..36ae175
--- /dev/null
@@ -0,0 +1,52 @@
+From 39873d1b0f843de2e3813a54fb62ba9ae3efbec5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Dec 2022 14:17:07 -0800
+Subject: net_sched: reject TCF_EM_SIMPLE case for complex ematch module
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit 9cd3fd2054c3b3055163accbf2f31a4426f10317 ]
+
+When TCF_EM_SIMPLE was introduced, it is supposed to be convenient
+for ematch implementation:
+
+https://lore.kernel.org/all/20050105110048.GO26856@postel.suug.ch/
+
+"You don't have to, providing a 32bit data chunk without TCF_EM_SIMPLE
+set will simply result in allocating & copy. It's an optimization,
+nothing more."
+
+So if an ematch module provides ops->datalen that means it wants a
+complex data structure (saved in its em->data) instead of a simple u32
+value. We should simply reject such a combination, otherwise this u32
+could be misinterpreted as a pointer.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-and-tested-by: syzbot+4caeae4c7103813598ae@syzkaller.appspotmail.com
+Reported-by: Jun Nie <jun.nie@linaro.org>
+Cc: Jamal Hadi Salim <jhs@mojatatu.com>
+Cc: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/ematch.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sched/ematch.c b/net/sched/ematch.c
+index f885bea5b452..b7154103e9cd 100644
+--- a/net/sched/ematch.c
++++ b/net/sched/ematch.c
+@@ -255,6 +255,8 @@ static int tcf_em_validate(struct tcf_proto *tp,
+                        * the value carried.
+                        */
+                       if (em_hdr->flags & TCF_EM_SIMPLE) {
++                              if (em->ops->datalen > 0)
++                                      goto errout;
+                               if (data_len < sizeof(u32))
+                                       goto errout;
+                               em->data = *(u32 *) data;
+-- 
+2.35.1
+
diff --git a/queue-5.10/netfilter-conntrack-set-icmpv6-redirects-as-related.patch b/queue-5.10/netfilter-conntrack-set-icmpv6-redirects-as-related.patch
new file mode 100644 (file)
index 0000000..e19d9b0
--- /dev/null
@@ -0,0 +1,173 @@
+From 2d8489282ead7f9f4223414cfddac13b54814184 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 16:00:09 +0100
+Subject: netfilter: conntrack: set icmpv6 redirects as RELATED
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 7d7cfb48d81353e826493d24c7cec7360950968f ]
+
+icmp conntrack will set icmp redirects as RELATED, but icmpv6 will not
+do this.
+
+For icmpv6, only icmp errors (code <= 128) are examined for RELATED state.
+ICMPV6 Redirects are part of neighbour discovery mechanism, those are
+handled by marking a selected subset (e.g.  neighbour solicitations) as
+UNTRACKED, but not REDIRECT -- they will thus be flagged as INVALID.
+
+Add minimal support for REDIRECTs.  No parsing of neighbour options is
+added for simplicity, so this will only check that we have the embeeded
+original header (ND_OPT_REDIRECT_HDR), and then attempt to do a flow
+lookup for this tuple.
+
+Also extend the existing test case to cover redirects.
+
+Fixes: 9fb9cbb1082d ("[NETFILTER]: Add nf_conntrack subsystem.")
+Reported-by: Eric Garver <eric@garver.life>
+Link: https://github.com/firewalld/firewalld/issues/1046
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Acked-by: Eric Garver <eric@garver.life>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_proto_icmpv6.c     | 53 +++++++++++++++++++
+ .../netfilter/conntrack_icmp_related.sh       | 36 ++++++++++++-
+ 2 files changed, 87 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_proto_icmpv6.c b/net/netfilter/nf_conntrack_proto_icmpv6.c
+index facd8c64ec4e..f1a87de1c60e 100644
+--- a/net/netfilter/nf_conntrack_proto_icmpv6.c
++++ b/net/netfilter/nf_conntrack_proto_icmpv6.c
+@@ -130,6 +130,56 @@ static void icmpv6_error_log(const struct sk_buff *skb,
+                              IPPROTO_ICMPV6, "%s", msg);
+ }
++static noinline_for_stack int
++nf_conntrack_icmpv6_redirect(struct nf_conn *tmpl, struct sk_buff *skb,
++                           unsigned int dataoff,
++                           const struct nf_hook_state *state)
++{
++      u8 hl = ipv6_hdr(skb)->hop_limit;
++      union nf_inet_addr outer_daddr;
++      union {
++              struct nd_opt_hdr nd_opt;
++              struct rd_msg rd_msg;
++      } tmp;
++      const struct nd_opt_hdr *nd_opt;
++      const struct rd_msg *rd_msg;
++
++      rd_msg = skb_header_pointer(skb, dataoff, sizeof(*rd_msg), &tmp.rd_msg);
++      if (!rd_msg) {
++              icmpv6_error_log(skb, state, "short redirect");
++              return -NF_ACCEPT;
++      }
++
++      if (rd_msg->icmph.icmp6_code != 0)
++              return NF_ACCEPT;
++
++      if (hl != 255 || !(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
++              icmpv6_error_log(skb, state, "invalid saddr or hoplimit for redirect");
++              return -NF_ACCEPT;
++      }
++
++      dataoff += sizeof(*rd_msg);
++
++      /* warning: rd_msg no longer usable after this call */
++      nd_opt = skb_header_pointer(skb, dataoff, sizeof(*nd_opt), &tmp.nd_opt);
++      if (!nd_opt || nd_opt->nd_opt_len == 0) {
++              icmpv6_error_log(skb, state, "redirect without options");
++              return -NF_ACCEPT;
++      }
++
++      /* We could call ndisc_parse_options(), but it would need
++       * skb_linearize() and a bit more work.
++       */
++      if (nd_opt->nd_opt_type != ND_OPT_REDIRECT_HDR)
++              return NF_ACCEPT;
++
++      memcpy(&outer_daddr.ip6, &ipv6_hdr(skb)->daddr,
++             sizeof(outer_daddr.ip6));
++      dataoff += 8;
++      return nf_conntrack_inet_error(tmpl, skb, dataoff, state,
++                                     IPPROTO_ICMPV6, &outer_daddr);
++}
++
+ int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
+                             struct sk_buff *skb,
+                             unsigned int dataoff,
+@@ -160,6 +210,9 @@ int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
+               return NF_ACCEPT;
+       }
++      if (icmp6h->icmp6_type == NDISC_REDIRECT)
++              return nf_conntrack_icmpv6_redirect(tmpl, skb, dataoff, state);
++
+       /* is not error message ? */
+       if (icmp6h->icmp6_type >= 128)
+               return NF_ACCEPT;
+diff --git a/tools/testing/selftests/netfilter/conntrack_icmp_related.sh b/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
+index b48e1833bc89..76645aaf2b58 100755
+--- a/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
++++ b/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
+@@ -35,6 +35,8 @@ cleanup() {
+       for i in 1 2;do ip netns del nsrouter$i;done
+ }
++trap cleanup EXIT
++
+ ipv4() {
+     echo -n 192.168.$1.2
+ }
+@@ -146,11 +148,17 @@ ip netns exec nsclient1 nft -f - <<EOF
+ table inet filter {
+       counter unknown { }
+       counter related { }
++      counter redir4 { }
++      counter redir6 { }
+       chain input {
+               type filter hook input priority 0; policy accept;
+-              meta l4proto { icmp, icmpv6 } ct state established,untracked accept
++              icmp type "redirect" ct state "related" counter name "redir4" accept
++              icmpv6 type "nd-redirect" ct state "related" counter name "redir6" accept
++
++              meta l4proto { icmp, icmpv6 } ct state established,untracked accept
+               meta l4proto { icmp, icmpv6 } ct state "related" counter name "related" accept
++
+               counter name "unknown" drop
+       }
+ }
+@@ -279,5 +287,29 @@ else
+       echo "ERROR: icmp error RELATED state test has failed"
+ fi
+-cleanup
++# add 'bad' route,  expect icmp REDIRECT to be generated
++ip netns exec nsclient1 ip route add 192.168.1.42 via 192.168.1.1
++ip netns exec nsclient1 ip route add dead:1::42 via dead:1::1
++
++ip netns exec "nsclient1" ping -q -c 2 192.168.1.42 > /dev/null
++
++expect="packets 1 bytes 112"
++check_counter nsclient1 "redir4" "$expect"
++if [ $? -ne 0 ];then
++      ret=1
++fi
++
++ip netns exec "nsclient1" ping -c 1 dead:1::42 > /dev/null
++expect="packets 1 bytes 192"
++check_counter nsclient1 "redir6" "$expect"
++if [ $? -ne 0 ];then
++      ret=1
++fi
++
++if [ $ret -eq 0 ];then
++      echo "PASS: icmp redirects had RELATED state"
++else
++      echo "ERROR: icmp redirect RELATED state test has failed"
++fi
++
+ exit $ret
+-- 
+2.35.1
+
diff --git a/queue-5.10/netfilter-flowtable-really-fix-nat-ipv6-offload.patch b/queue-5.10/netfilter-flowtable-really-fix-nat-ipv6-offload.patch
new file mode 100644 (file)
index 0000000..bd082b1
--- /dev/null
@@ -0,0 +1,50 @@
+From d4cb404fbe9d8a30e1447b8e74121c0374c30511 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 20:35:29 +0800
+Subject: netfilter: flowtable: really fix NAT IPv6 offload
+
+From: Qingfang DENG <dqfext@gmail.com>
+
+[ Upstream commit 5fb45f95eec682621748b7cb012c6a8f0f981e6a ]
+
+The for-loop was broken from the start. It translates to:
+
+       for (i = 0; i < 4; i += 4)
+
+which means the loop statement is run only once, so only the highest
+32-bit of the IPv6 address gets mangled.
+
+Fix the loop increment.
+
+Fixes: 0e07e25b481a ("netfilter: flowtable: fix NAT IPv6 offload mangling")
+Fixes: 5c27d8d76ce8 ("netfilter: nf_flow_table_offload: add IPv6 support")
+Signed-off-by: Qingfang DENG <dqfext@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_flow_table_offload.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
+index 28306cb66719..746ca77d0aad 100644
+--- a/net/netfilter/nf_flow_table_offload.c
++++ b/net/netfilter/nf_flow_table_offload.c
+@@ -305,12 +305,12 @@ static void flow_offload_ipv6_mangle(struct nf_flow_rule *flow_rule,
+                                    const __be32 *addr, const __be32 *mask)
+ {
+       struct flow_action_entry *entry;
+-      int i, j;
++      int i;
+-      for (i = 0, j = 0; i < sizeof(struct in6_addr) / sizeof(u32); i += sizeof(u32), j++) {
++      for (i = 0; i < sizeof(struct in6_addr) / sizeof(u32); i++) {
+               entry = flow_action_entry_next(flow_rule);
+               flow_offload_mangle(entry, FLOW_ACT_MANGLE_HDR_TYPE_IP6,
+-                                  offset + i, &addr[j], mask);
++                                  offset + i * sizeof(u32), &addr[i], mask);
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/nfc-pn533-clear-nfc_target-before-being-used.patch b/queue-5.10/nfc-pn533-clear-nfc_target-before-being-used.patch
new file mode 100644 (file)
index 0000000..c5651a1
--- /dev/null
@@ -0,0 +1,73 @@
+From 86eb61825319b89e5737b2fc2c4ef5a8a53b42c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Dec 2022 10:51:39 +0900
+Subject: nfc: pn533: Clear nfc_target before being used
+
+From: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+
+[ Upstream commit 9f28157778ede0d4f183f7ab3b46995bb400abbe ]
+
+Fix a slab-out-of-bounds read that occurs in nla_put() called from
+nfc_genl_send_target() when target->sensb_res_len, which is duplicated
+from an nfc_target in pn533, is too large as the nfc_target is not
+properly initialized and retains garbage values. Clear nfc_targets with
+memset() before they are used.
+
+Found by a modified version of syzkaller.
+
+BUG: KASAN: slab-out-of-bounds in nla_put
+Call Trace:
+ memcpy
+ nla_put
+ nfc_genl_dump_targets
+ genl_lock_dumpit
+ netlink_dump
+ __netlink_dump_start
+ genl_family_rcv_msg_dumpit
+ genl_rcv_msg
+ netlink_rcv_skb
+ genl_rcv
+ netlink_unicast
+ netlink_sendmsg
+ sock_sendmsg
+ ____sys_sendmsg
+ ___sys_sendmsg
+ __sys_sendmsg
+ do_syscall_64
+
+Fixes: 673088fb42d0 ("NFC: pn533: Send ATR_REQ directly for active device detection")
+Fixes: 361f3cb7f9cf ("NFC: DEP link hook implementation for pn533")
+Signed-off-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20221214015139.119673-1-linuxlovemin@yonsei.ac.kr
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/pn533/pn533.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c
+index 8d7e29d953b7..87e1296c6838 100644
+--- a/drivers/nfc/pn533/pn533.c
++++ b/drivers/nfc/pn533/pn533.c
+@@ -1319,6 +1319,8 @@ static int pn533_poll_dep_complete(struct pn533 *dev, void *arg,
+       if (IS_ERR(resp))
+               return PTR_ERR(resp);
++      memset(&nfc_target, 0, sizeof(struct nfc_target));
++
+       rsp = (struct pn533_cmd_jump_dep_response *)resp->data;
+       rc = rsp->status & PN533_CMD_RET_MASK;
+@@ -1960,6 +1962,8 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
+               dev_dbg(dev->dev, "Creating new target\n");
++              memset(&nfc_target, 0, sizeof(struct nfc_target));
++
+               nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
+               nfc_target.nfcid1_len = 10;
+               memcpy(nfc_target.nfcid1, rsp->nfcid3t, nfc_target.nfcid1_len);
+-- 
+2.35.1
+
diff --git a/queue-5.10/nfs-fix-an-oops-in-nfs_d_automount.patch b/queue-5.10/nfs-fix-an-oops-in-nfs_d_automount.patch
new file mode 100644 (file)
index 0000000..7a1c483
--- /dev/null
@@ -0,0 +1,36 @@
+From dfdce24b78cfe4079fd2706785878f8454d3f52f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 17:30:39 -0500
+Subject: NFS: Fix an Oops in nfs_d_automount()
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 35e3b6ae84935d0d7ff76cbdaa83411b0ad5e471 ]
+
+When mounting from a NFSv4 referral, path->dentry can end up being a
+negative dentry, so derive the struct nfs_server from the dentry
+itself instead.
+
+Fixes: 2b0143b5c986 ("VFS: normal filesystems (and lustre): d_inode() annotations")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/namespace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
+index 2bcbe38afe2e..1f03445b5cb4 100644
+--- a/fs/nfs/namespace.c
++++ b/fs/nfs/namespace.c
+@@ -147,7 +147,7 @@ struct vfsmount *nfs_d_automount(struct path *path)
+       struct nfs_fs_context *ctx;
+       struct fs_context *fc;
+       struct vfsmount *mnt = ERR_PTR(-ENOMEM);
+-      struct nfs_server *server = NFS_SERVER(d_inode(path->dentry));
++      struct nfs_server *server = NFS_SB(path->dentry->d_sb);
+       struct nfs_client *client = server->nfs_client;
+       int timeout = READ_ONCE(nfs_mountpoint_expiry_timeout);
+       int ret;
+-- 
+2.35.1
+
diff --git a/queue-5.10/nfsd-don-t-call-nfsd_file_put-from-client-states-seq.patch b/queue-5.10/nfsd-don-t-call-nfsd_file_put-from-client-states-seq.patch
new file mode 100644 (file)
index 0000000..78e2cae
--- /dev/null
@@ -0,0 +1,147 @@
+From ce2d4c80a72cdb7158abf53d4d0565749df160ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Oct 2022 08:13:53 -0400
+Subject: nfsd: don't call nfsd_file_put from client states seqfile display
+
+From: Jeff Layton <jlayton@kernel.org>
+
+[ Upstream commit e0aa651068bfd520afcd357af8ecd2de005fc83d ]
+
+We had a report of this:
+
+    BUG: sleeping function called from invalid context at fs/nfsd/filecache.c:440
+
+...with a stack trace showing nfsd_file_put being called from
+nfs4_show_open. This code has always tried to call fput while holding a
+spinlock, but we recently changed this to use the filecache, and that
+started triggering the might_sleep() in nfsd_file_put.
+
+states_start takes and holds the cl_lock while iterating over the
+client's states, and we can't sleep with that held.
+
+Have the various nfs4_show_* functions instead hold the fi_lock instead
+of taking a nfsd_file reference.
+
+Fixes: 78599c42ae3c ("nfsd4: add file to display list of client's opens")
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=2138357
+Reported-by: Zhi Li <yieli@redhat.com>
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4state.c | 51 +++++++++++++++++++++++++++++----------------
+ 1 file changed, 33 insertions(+), 18 deletions(-)
+
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index 665d0eaeb8db..9a47cc66963f 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -507,15 +507,26 @@ find_any_file(struct nfs4_file *f)
+       return ret;
+ }
+-static struct nfsd_file *find_deleg_file(struct nfs4_file *f)
++static struct nfsd_file *find_any_file_locked(struct nfs4_file *f)
+ {
+-      struct nfsd_file *ret = NULL;
++      lockdep_assert_held(&f->fi_lock);
++
++      if (f->fi_fds[O_RDWR])
++              return f->fi_fds[O_RDWR];
++      if (f->fi_fds[O_WRONLY])
++              return f->fi_fds[O_WRONLY];
++      if (f->fi_fds[O_RDONLY])
++              return f->fi_fds[O_RDONLY];
++      return NULL;
++}
++
++static struct nfsd_file *find_deleg_file_locked(struct nfs4_file *f)
++{
++      lockdep_assert_held(&f->fi_lock);
+-      spin_lock(&f->fi_lock);
+       if (f->fi_deleg_file)
+-              ret = nfsd_file_get(f->fi_deleg_file);
+-      spin_unlock(&f->fi_lock);
+-      return ret;
++              return f->fi_deleg_file;
++      return NULL;
+ }
+ static atomic_long_t num_delegations;
+@@ -2462,9 +2473,11 @@ static int nfs4_show_open(struct seq_file *s, struct nfs4_stid *st)
+       ols = openlockstateid(st);
+       oo = ols->st_stateowner;
+       nf = st->sc_file;
+-      file = find_any_file(nf);
++
++      spin_lock(&nf->fi_lock);
++      file = find_any_file_locked(nf);
+       if (!file)
+-              return 0;
++              goto out;
+       seq_printf(s, "- ");
+       nfs4_show_stateid(s, &st->sc_stateid);
+@@ -2486,8 +2499,8 @@ static int nfs4_show_open(struct seq_file *s, struct nfs4_stid *st)
+       seq_printf(s, ", ");
+       nfs4_show_owner(s, oo);
+       seq_printf(s, " }\n");
+-      nfsd_file_put(file);
+-
++out:
++      spin_unlock(&nf->fi_lock);
+       return 0;
+ }
+@@ -2501,9 +2514,10 @@ static int nfs4_show_lock(struct seq_file *s, struct nfs4_stid *st)
+       ols = openlockstateid(st);
+       oo = ols->st_stateowner;
+       nf = st->sc_file;
+-      file = find_any_file(nf);
++      spin_lock(&nf->fi_lock);
++      file = find_any_file_locked(nf);
+       if (!file)
+-              return 0;
++              goto out;
+       seq_printf(s, "- ");
+       nfs4_show_stateid(s, &st->sc_stateid);
+@@ -2523,8 +2537,8 @@ static int nfs4_show_lock(struct seq_file *s, struct nfs4_stid *st)
+       seq_printf(s, ", ");
+       nfs4_show_owner(s, oo);
+       seq_printf(s, " }\n");
+-      nfsd_file_put(file);
+-
++out:
++      spin_unlock(&nf->fi_lock);
+       return 0;
+ }
+@@ -2536,9 +2550,10 @@ static int nfs4_show_deleg(struct seq_file *s, struct nfs4_stid *st)
+       ds = delegstateid(st);
+       nf = st->sc_file;
+-      file = find_deleg_file(nf);
++      spin_lock(&nf->fi_lock);
++      file = find_deleg_file_locked(nf);
+       if (!file)
+-              return 0;
++              goto out;
+       seq_printf(s, "- ");
+       nfs4_show_stateid(s, &st->sc_stateid);
+@@ -2554,8 +2569,8 @@ static int nfs4_show_deleg(struct seq_file *s, struct nfs4_stid *st)
+       seq_printf(s, ", ");
+       nfs4_show_fname(s, file);
+       seq_printf(s, " }\n");
+-      nfsd_file_put(file);
+-
++out:
++      spin_unlock(&nf->fi_lock);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/nfsd-remove-spurious-cb_setup_err-tracepoint.patch b/queue-5.10/nfsd-remove-spurious-cb_setup_err-tracepoint.patch
new file mode 100644 (file)
index 0000000..752ca8c
--- /dev/null
@@ -0,0 +1,39 @@
+From 1802f99a1f9fb3bec05a3cc5ab53c85f171c0dc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 May 2021 15:56:56 -0400
+Subject: NFSD: Remove spurious cb_setup_err tracepoint
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 9f57c6062bf3ce2c6ab9ba60040b34e8134ef259 ]
+
+This path is not really an error path, so the tracepoint I added
+there is just noise.
+
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Stable-dep-of: 3bc8edc98bd4 ("nfsd: under NFSv4.1, fix double svc_xprt_put on rpc_create failure")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4callback.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
+index 7325592b456e..4eceff561e5a 100644
+--- a/fs/nfsd/nfs4callback.c
++++ b/fs/nfsd/nfs4callback.c
+@@ -915,10 +915,8 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
+               args.authflavor = clp->cl_cred.cr_flavor;
+               clp->cl_cb_ident = conn->cb_ident;
+       } else {
+-              if (!conn->cb_xprt) {
+-                      trace_nfsd_cb_setup_err(clp, -EINVAL);
++              if (!conn->cb_xprt)
+                       return -EINVAL;
+-              }
+               clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
+               clp->cl_cb_session = ses;
+               args.bc_xprt = conn->cb_xprt;
+-- 
+2.35.1
+
diff --git a/queue-5.10/nfsd-under-nfsv4.1-fix-double-svc_xprt_put-on-rpc_cr.patch b/queue-5.10/nfsd-under-nfsv4.1-fix-double-svc_xprt_put-on-rpc_cr.patch
new file mode 100644 (file)
index 0000000..a20acc4
--- /dev/null
@@ -0,0 +1,87 @@
+From 1afb2ce22ebd99d4c655333cbf5b35c487d7ec30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Dec 2022 13:11:06 +0200
+Subject: nfsd: under NFSv4.1, fix double svc_xprt_put on rpc_create failure
+
+From: Dan Aloni <dan.aloni@vastdata.com>
+
+[ Upstream commit 3bc8edc98bd43540dbe648e4ef91f443d6d20a24 ]
+
+On error situation `clp->cl_cb_conn.cb_xprt` should not be given
+a reference to the xprt otherwise both client cleanup and the
+error handling path of the caller call to put it. Better to
+delay handing over the reference to a later branch.
+
+[   72.530665] refcount_t: underflow; use-after-free.
+[   72.531933] WARNING: CPU: 0 PID: 173 at lib/refcount.c:28 refcount_warn_saturate+0xcf/0x120
+[   72.533075] Modules linked in: nfsd(OE) nfsv4(OE) nfsv3(OE) nfs(OE) lockd(OE) compat_nfs_ssc(OE) nfs_acl(OE) rpcsec_gss_krb5(OE) auth_rpcgss(OE) rpcrdma(OE) dns_resolver fscache netfs grace rdma_cm iw_cm ib_cm sunrpc(OE) mlx5_ib mlx5_core mlxfw pci_hyperv_intf ib_uverbs ib_core xt_MASQUERADE nf_conntrack_netlink nft_counter xt_addrtype nft_compat br_netfilter bridge stp llc nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set overlay nf_tables nfnetlink crct10dif_pclmul crc32_pclmul ghash_clmulni_intel xfs serio_raw virtio_net virtio_blk net_failover failover fuse [last unloaded: sunrpc]
+[   72.540389] CPU: 0 PID: 173 Comm: kworker/u16:5 Tainted: G           OE     5.15.82-dan #1
+[   72.541511] Hardware name: Red Hat KVM/RHEL-AV, BIOS 1.16.0-3.module+el8.7.0+1084+97b81f61 04/01/2014
+[   72.542717] Workqueue: nfsd4_callbacks nfsd4_run_cb_work [nfsd]
+[   72.543575] RIP: 0010:refcount_warn_saturate+0xcf/0x120
+[   72.544299] Code: 55 00 0f 0b 5d e9 01 50 98 00 80 3d 75 9e 39 08 00 0f 85 74 ff ff ff 48 c7 c7 e8 d1 60 8e c6 05 61 9e 39 08 01 e8 f6 51 55 00 <0f> 0b 5d e9 d9 4f 98 00 80 3d 4b 9e 39 08 00 0f 85 4c ff ff ff 48
+[   72.546666] RSP: 0018:ffffb3f841157cf0 EFLAGS: 00010286
+[   72.547393] RAX: 0000000000000026 RBX: ffff89ac6231d478 RCX: 0000000000000000
+[   72.548324] RDX: ffff89adb7c2c2c0 RSI: ffff89adb7c205c0 RDI: ffff89adb7c205c0
+[   72.549271] RBP: ffffb3f841157cf0 R08: 0000000000000000 R09: c0000000ffefffff
+[   72.550209] R10: 0000000000000001 R11: ffffb3f841157ad0 R12: ffff89ac6231d180
+[   72.551142] R13: ffff89ac6231d478 R14: ffff89ac40c06180 R15: ffff89ac6231d4b0
+[   72.552089] FS:  0000000000000000(0000) GS:ffff89adb7c00000(0000) knlGS:0000000000000000
+[   72.553175] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   72.553934] CR2: 0000563a310506a8 CR3: 0000000109a66000 CR4: 0000000000350ef0
+[   72.554874] Call Trace:
+[   72.555278]  <TASK>
+[   72.555614]  svc_xprt_put+0xaf/0xe0 [sunrpc]
+[   72.556276]  nfsd4_process_cb_update.isra.11+0xb7/0x410 [nfsd]
+[   72.557087]  ? update_load_avg+0x82/0x610
+[   72.557652]  ? cpuacct_charge+0x60/0x70
+[   72.558212]  ? dequeue_entity+0xdb/0x3e0
+[   72.558765]  ? queued_spin_unlock+0x9/0x20
+[   72.559358]  nfsd4_run_cb_work+0xfc/0x270 [nfsd]
+[   72.560031]  process_one_work+0x1df/0x390
+[   72.560600]  worker_thread+0x37/0x3b0
+[   72.561644]  ? process_one_work+0x390/0x390
+[   72.562247]  kthread+0x12f/0x150
+[   72.562710]  ? set_kthread_struct+0x50/0x50
+[   72.563309]  ret_from_fork+0x22/0x30
+[   72.563818]  </TASK>
+[   72.564189] ---[ end trace 031117b1c72ec616 ]---
+[   72.566019] list_add corruption. next->prev should be prev (ffff89ac4977e538), but was ffff89ac4763e018. (next=ffff89ac4763e018).
+[   72.567647] ------------[ cut here ]------------
+
+Fixes: a4abc6b12eb1 ("nfsd: Fix svc_xprt refcnt leak when setup callback client failed")
+Cc: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Cc: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Dan Aloni <dan.aloni@vastdata.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4callback.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
+index 4eceff561e5a..af2064e36ac6 100644
+--- a/fs/nfsd/nfs4callback.c
++++ b/fs/nfsd/nfs4callback.c
+@@ -917,7 +917,6 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
+       } else {
+               if (!conn->cb_xprt)
+                       return -EINVAL;
+-              clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
+               clp->cl_cb_session = ses;
+               args.bc_xprt = conn->cb_xprt;
+               args.prognumber = clp->cl_cb_session->se_cb_prog;
+@@ -937,6 +936,9 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
+               rpc_shutdown_client(client);
+               return -ENOMEM;
+       }
++
++      if (clp->cl_minorversion != 0)
++              clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
+       clp->cl_cb_client = client;
+       clp->cl_cb_cred = cred;
+       trace_nfsd_cb_setup(clp);
+-- 
+2.35.1
+
diff --git a/queue-5.10/nfsv4-fix-a-deadlock-between-nfs4_open_recover_helpe.patch b/queue-5.10/nfsv4-fix-a-deadlock-between-nfs4_open_recover_helpe.patch
new file mode 100644 (file)
index 0000000..926fb12
--- /dev/null
@@ -0,0 +1,73 @@
+From 3d3a1695cb3845389ca0c0ccf374770375a6bc13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 13:20:01 -0400
+Subject: NFSv4: Fix a deadlock between nfs4_open_recover_helper() and
+ delegreturn
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 51069e4aef6257b0454057359faed0ab0c9af083 ]
+
+If we're asked to recover open state while a delegation return is
+outstanding, then the state manager thread cannot use a cached open, so
+if the server returns a delegation, we can end up deadlocked behind the
+pending delegreturn.
+To avoid this problem, let's just ask the server not to give us a
+delegation unless we're explicitly reclaiming one.
+
+Fixes: be36e185bd26 ("NFSv4: nfs4_open_recover_helper() must set share access")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4proc.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 15550d673e61..ee46ab09e330 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -2126,18 +2126,18 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
+ }
+ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata,
+-              fmode_t fmode)
++                                  fmode_t fmode)
+ {
+       struct nfs4_state *newstate;
++      struct nfs_server *server = NFS_SB(opendata->dentry->d_sb);
++      int openflags = opendata->o_arg.open_flags;
+       int ret;
+       if (!nfs4_mode_match_open_stateid(opendata->state, fmode))
+               return 0;
+-      opendata->o_arg.open_flags = 0;
+       opendata->o_arg.fmode = fmode;
+-      opendata->o_arg.share_access = nfs4_map_atomic_open_share(
+-                      NFS_SB(opendata->dentry->d_sb),
+-                      fmode, 0);
++      opendata->o_arg.share_access =
++              nfs4_map_atomic_open_share(server, fmode, openflags);
+       memset(&opendata->o_res, 0, sizeof(opendata->o_res));
+       memset(&opendata->c_res, 0, sizeof(opendata->c_res));
+       nfs4_init_opendata_res(opendata);
+@@ -2713,10 +2713,15 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
+       struct nfs4_opendata *opendata;
+       int ret;
+-      opendata = nfs4_open_recoverdata_alloc(ctx, state,
+-                      NFS4_OPEN_CLAIM_FH);
++      opendata = nfs4_open_recoverdata_alloc(ctx, state, NFS4_OPEN_CLAIM_FH);
+       if (IS_ERR(opendata))
+               return PTR_ERR(opendata);
++      /*
++       * We're not recovering a delegation, so ask for no delegation.
++       * Otherwise the recovery thread could deadlock with an outstanding
++       * delegation return.
++       */
++      opendata->o_arg.open_flags = O_DIRECT;
+       ret = nfs4_open_recover(opendata, state);
+       if (ret == -ESTALE)
+               d_drop(ctx->dentry);
+-- 
+2.35.1
+
diff --git a/queue-5.10/nfsv4.2-clear-fattr4_word2_security_label-when-done-.patch b/queue-5.10/nfsv4.2-clear-fattr4_word2_security_label-when-done-.patch
new file mode 100644 (file)
index 0000000..97c47f2
--- /dev/null
@@ -0,0 +1,42 @@
+From 627bb105798f1625b3ed20f4a415c097f3bf868b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 16:44:47 -0400
+Subject: NFSv4.2: Clear FATTR4_WORD2_SECURITY_LABEL when done decoding
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit eef7314caf2d73a94b68ba293cd105154d3a664e ]
+
+We need to clear the FATTR4_WORD2_SECURITY_LABEL bitmap flag
+irrespective of whether or not the label is too long.
+
+Fixes: aa9c2669626c ("NFS: Client implementation of Labeled-NFS")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4xdr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
+index e2f0e3446e22..f8c89f9f4d52 100644
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -4166,6 +4166,7 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
+               p = xdr_inline_decode(xdr, len);
+               if (unlikely(!p))
+                       return -EIO;
++              bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
+               if (len < NFS4_MAXLABELLEN) {
+                       if (label) {
+                               if (label->len) {
+@@ -4178,7 +4179,6 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
+                               label->lfs = lfs;
+                               status = NFS_ATTR_FATTR_V4_SECURITY_LABEL;
+                       }
+-                      bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
+               } else
+                       printk(KERN_WARNING "%s: label too long (%u)!\n",
+                                       __func__, len);
+-- 
+2.35.1
+
diff --git a/queue-5.10/nfsv4.2-fix-a-memory-stomp-in-decode_attr_security_l.patch b/queue-5.10/nfsv4.2-fix-a-memory-stomp-in-decode_attr_security_l.patch
new file mode 100644 (file)
index 0000000..e7bd11b
--- /dev/null
@@ -0,0 +1,43 @@
+From b5062258f691a3777ab1f4e5b44dd189524f57ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 18:21:14 -0400
+Subject: NFSv4.2: Fix a memory stomp in decode_attr_security_label
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 43c1031f7110967c240cb6e922adcfc4b8899183 ]
+
+We must not change the value of label->len if it is zero, since that
+indicates we stored a label.
+
+Fixes: b4487b935452 ("nfs: Fix getxattr kernel panic and memory overflow")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4xdr.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
+index f8c89f9f4d52..f1e599553f2b 100644
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -4168,12 +4168,10 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
+                       return -EIO;
+               bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
+               if (len < NFS4_MAXLABELLEN) {
+-                      if (label) {
+-                              if (label->len) {
+-                                      if (label->len < len)
+-                                              return -ERANGE;
+-                                      memcpy(label->label, p, len);
+-                              }
++                      if (label && label->len) {
++                              if (label->len < len)
++                                      return -ERANGE;
++                              memcpy(label->label, p, len);
+                               label->len = len;
+                               label->pi = pi;
+                               label->lfs = lfs;
+-- 
+2.35.1
+
diff --git a/queue-5.10/nfsv4.2-fix-initialisation-of-struct-nfs4_label.patch b/queue-5.10/nfsv4.2-fix-initialisation-of-struct-nfs4_label.patch
new file mode 100644 (file)
index 0000000..c95215c
--- /dev/null
@@ -0,0 +1,83 @@
+From 15b6df237069f5b1c618659f91de48d901eb34c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Oct 2022 13:12:11 -0400
+Subject: NFSv4.2: Fix initialisation of struct nfs4_label
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit c528f70f504434eaff993a5ddd52203a2010d51f ]
+
+The call to nfs4_label_init_security() should return a fully initialised
+label.
+
+Fixes: aa9c2669626c ("NFS: Client implementation of Labeled-NFS")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4proc.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 36af3734ac87..15550d673e61 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -130,6 +130,11 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
+       if (nfs_server_capable(dir, NFS_CAP_SECURITY_LABEL) == 0)
+               return NULL;
++      label->lfs = 0;
++      label->pi = 0;
++      label->len = 0;
++      label->label = NULL;
++
+       err = security_dentry_init_security(dentry, sattr->ia_mode,
+                               &dentry->d_name, (void **)&label->label, &label->len);
+       if (err == 0)
+@@ -3793,7 +3798,7 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx,
+               int open_flags, struct iattr *attr, int *opened)
+ {
+       struct nfs4_state *state;
+-      struct nfs4_label l = {0, 0, 0, NULL}, *label = NULL;
++      struct nfs4_label l, *label;
+       label = nfs4_label_init_security(dir, ctx->dentry, attr, &l);
+@@ -4557,7 +4562,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
+                int flags)
+ {
+       struct nfs_server *server = NFS_SERVER(dir);
+-      struct nfs4_label l, *ilabel = NULL;
++      struct nfs4_label l, *ilabel;
+       struct nfs_open_context *ctx;
+       struct nfs4_state *state;
+       int status = 0;
+@@ -4916,7 +4921,7 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
+       struct nfs4_exception exception = {
+               .interruptible = true,
+       };
+-      struct nfs4_label l, *label = NULL;
++      struct nfs4_label l, *label;
+       int err;
+       label = nfs4_label_init_security(dir, dentry, sattr, &l);
+@@ -4957,7 +4962,7 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
+       struct nfs4_exception exception = {
+               .interruptible = true,
+       };
+-      struct nfs4_label l, *label = NULL;
++      struct nfs4_label l, *label;
+       int err;
+       label = nfs4_label_init_security(dir, dentry, sattr, &l);
+@@ -5078,7 +5083,7 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
+       struct nfs4_exception exception = {
+               .interruptible = true,
+       };
+-      struct nfs4_label l, *label = NULL;
++      struct nfs4_label l, *label;
+       int err;
+       label = nfs4_label_init_security(dir, dentry, sattr, &l);
+-- 
+2.35.1
+
diff --git a/queue-5.10/nfsv4.x-fail-client-initialisation-if-state-manager-.patch b/queue-5.10/nfsv4.x-fail-client-initialisation-if-state-manager-.patch
new file mode 100644 (file)
index 0000000..9c05c62
--- /dev/null
@@ -0,0 +1,37 @@
+From 87c1de54e7cf4cbbe68bcf56579cc18ea69959a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 12:42:59 -0500
+Subject: NFSv4.x: Fail client initialisation if state manager thread can't run
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit b4e4f66901658fae0614dea5bf91062a5387eda7 ]
+
+If the state manager thread fails to start, then we should just mark the
+client initialisation as failed so that other processes or threads don't
+get stuck in nfs_wait_client_init_complete().
+
+Reported-by: ChenXiaoSong <chenxiaosong2@huawei.com>
+Fixes: 4697bd5e9419 ("NFSv4: Fix a race in the net namespace mount notification")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4state.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+index a77a3d8c0b3f..175b2e064003 100644
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1226,6 +1226,8 @@ void nfs4_schedule_state_manager(struct nfs_client *clp)
+       if (IS_ERR(task)) {
+               printk(KERN_ERR "%s: kthread_run: %ld\n",
+                       __func__, PTR_ERR(task));
++              if (!nfs_client_init_is_complete(clp))
++                      nfs_mark_client_ready(clp, PTR_ERR(task));
+               nfs4_clear_state_manager_bit(clp);
+               nfs_put_client(clp);
+               module_put(THIS_MODULE);
+-- 
+2.35.1
+
diff --git a/queue-5.10/nilfs2-fix-shift-out-of-bounds-due-to-too-large-expo.patch b/queue-5.10/nilfs2-fix-shift-out-of-bounds-due-to-too-large-expo.patch
new file mode 100644 (file)
index 0000000..35b84e1
--- /dev/null
@@ -0,0 +1,110 @@
+From 896a0c1c080c6cfabaeb106b475d602a7fb3d302 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 13:43:06 +0900
+Subject: nilfs2: fix shift-out-of-bounds due to too large exponent of block
+ size
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+[ Upstream commit ebeccaaef67a4895d2496ab8d9c2fb8d89201211 ]
+
+If field s_log_block_size of superblock data is corrupted and too large,
+init_nilfs() and load_nilfs() still can trigger a shift-out-of-bounds
+warning followed by a kernel panic (if panic_on_warn is set):
+
+ shift exponent 38973 is too large for 32-bit type 'int'
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0xcd/0x134
+  ubsan_epilogue+0xb/0x50
+  __ubsan_handle_shift_out_of_bounds.cold.12+0x17b/0x1f5
+  init_nilfs.cold.11+0x18/0x1d [nilfs2]
+  nilfs_mount+0x9b5/0x12b0 [nilfs2]
+  ...
+
+This fixes the issue by adding and using a new helper function for getting
+block size with sanity check.
+
+Link: https://lkml.kernel.org/r/20221027044306.42774-3-konishi.ryusuke@gmail.com
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/the_nilfs.c | 42 ++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 38 insertions(+), 4 deletions(-)
+
+diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
+index 6e2ccdd79c89..211937054c31 100644
+--- a/fs/nilfs2/the_nilfs.c
++++ b/fs/nilfs2/the_nilfs.c
+@@ -193,6 +193,34 @@ static int nilfs_store_log_cursor(struct the_nilfs *nilfs,
+       return ret;
+ }
++/**
++ * nilfs_get_blocksize - get block size from raw superblock data
++ * @sb: super block instance
++ * @sbp: superblock raw data buffer
++ * @blocksize: place to store block size
++ *
++ * nilfs_get_blocksize() calculates the block size from the block size
++ * exponent information written in @sbp and stores it in @blocksize,
++ * or aborts with an error message if it's too large.
++ *
++ * Return Value: On success, 0 is returned. If the block size is too
++ * large, -EINVAL is returned.
++ */
++static int nilfs_get_blocksize(struct super_block *sb,
++                             struct nilfs_super_block *sbp, int *blocksize)
++{
++      unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size);
++
++      if (unlikely(shift_bits >
++                   ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS)) {
++              nilfs_err(sb, "too large filesystem blocksize: 2 ^ %u KiB",
++                        shift_bits);
++              return -EINVAL;
++      }
++      *blocksize = BLOCK_SIZE << shift_bits;
++      return 0;
++}
++
+ /**
+  * load_nilfs - load and recover the nilfs
+  * @nilfs: the_nilfs structure to be released
+@@ -246,11 +274,15 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
+               nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
+               /* verify consistency between two super blocks */
+-              blocksize = BLOCK_SIZE << le32_to_cpu(sbp[0]->s_log_block_size);
++              err = nilfs_get_blocksize(sb, sbp[0], &blocksize);
++              if (err)
++                      goto scan_error;
++
+               if (blocksize != nilfs->ns_blocksize) {
+                       nilfs_warn(sb,
+                                  "blocksize differs between two super blocks (%d != %d)",
+                                  blocksize, nilfs->ns_blocksize);
++                      err = -EINVAL;
+                       goto scan_error;
+               }
+@@ -609,9 +641,11 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
+       if (err)
+               goto failed_sbh;
+-      blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
+-      if (blocksize < NILFS_MIN_BLOCK_SIZE ||
+-          blocksize > NILFS_MAX_BLOCK_SIZE) {
++      err = nilfs_get_blocksize(sb, sbp, &blocksize);
++      if (err)
++              goto failed_sbh;
++
++      if (blocksize < NILFS_MIN_BLOCK_SIZE) {
+               nilfs_err(sb,
+                         "couldn't mount because of unsupported filesystem blocksize %d",
+                         blocksize);
+-- 
+2.35.1
+
diff --git a/queue-5.10/nilfs2-fix-shift-out-of-bounds-overflow-in-nilfs_sb2.patch b/queue-5.10/nilfs2-fix-shift-out-of-bounds-overflow-in-nilfs_sb2.patch
new file mode 100644 (file)
index 0000000..96840d8
--- /dev/null
@@ -0,0 +1,114 @@
+From 294a2bbc52d89f45eb583a8a47d5fe6f7df51f30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 13:43:05 +0900
+Subject: nilfs2: fix shift-out-of-bounds/overflow in nilfs_sb2_bad_offset()
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+[ Upstream commit 610a2a3d7d8be3537458a378ec69396a76c385b6 ]
+
+Patch series "nilfs2: fix UBSAN shift-out-of-bounds warnings on mount
+time".
+
+The first patch fixes a bug reported by syzbot, and the second one fixes
+the remaining bug of the same kind.  Although they are triggered by the
+same super block data anomaly, I divided it into the above two because the
+details of the issues and how to fix it are different.
+
+Both are required to eliminate the shift-out-of-bounds issues at mount
+time.
+
+This patch (of 2):
+
+If the block size exponent information written in an on-disk superblock is
+corrupted, nilfs_sb2_bad_offset helper function can trigger
+shift-out-of-bounds warning followed by a kernel panic (if panic_on_warn
+is set):
+
+ shift exponent 38983 is too large for 64-bit type 'unsigned long long'
+ Call Trace:
+  <TASK>
+  __dump_stack lib/dump_stack.c:88 [inline]
+  dump_stack_lvl+0x1b1/0x28e lib/dump_stack.c:106
+  ubsan_epilogue lib/ubsan.c:151 [inline]
+  __ubsan_handle_shift_out_of_bounds+0x33d/0x3b0 lib/ubsan.c:322
+  nilfs_sb2_bad_offset fs/nilfs2/the_nilfs.c:449 [inline]
+  nilfs_load_super_block+0xdf5/0xe00 fs/nilfs2/the_nilfs.c:523
+  init_nilfs+0xb7/0x7d0 fs/nilfs2/the_nilfs.c:577
+  nilfs_fill_super+0xb1/0x5d0 fs/nilfs2/super.c:1047
+  nilfs_mount+0x613/0x9b0 fs/nilfs2/super.c:1317
+  ...
+
+In addition, since nilfs_sb2_bad_offset() performs multiplication without
+considering the upper bound, the computation may overflow if the disk
+layout parameters are not normal.
+
+This fixes these issues by inserting preliminary sanity checks for those
+parameters and by converting the comparison from one involving
+multiplication and left bit-shifting to one using division and right
+bit-shifting.
+
+Link: https://lkml.kernel.org/r/20221027044306.42774-1-konishi.ryusuke@gmail.com
+Link: https://lkml.kernel.org/r/20221027044306.42774-2-konishi.ryusuke@gmail.com
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Reported-by: syzbot+e91619dd4c11c4960706@syzkaller.appspotmail.com
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/the_nilfs.c | 31 +++++++++++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
+index ce103dd39b89..6e2ccdd79c89 100644
+--- a/fs/nilfs2/the_nilfs.c
++++ b/fs/nilfs2/the_nilfs.c
+@@ -13,6 +13,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/backing-dev.h>
+ #include <linux/random.h>
++#include <linux/log2.h>
+ #include <linux/crc32.h>
+ #include "nilfs.h"
+ #include "segment.h"
+@@ -443,11 +444,33 @@ static int nilfs_valid_sb(struct nilfs_super_block *sbp)
+       return crc == le32_to_cpu(sbp->s_sum);
+ }
+-static int nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
++/**
++ * nilfs_sb2_bad_offset - check the location of the second superblock
++ * @sbp: superblock raw data buffer
++ * @offset: byte offset of second superblock calculated from device size
++ *
++ * nilfs_sb2_bad_offset() checks if the position on the second
++ * superblock is valid or not based on the filesystem parameters
++ * stored in @sbp.  If @offset points to a location within the segment
++ * area, or if the parameters themselves are not normal, it is
++ * determined to be invalid.
++ *
++ * Return Value: true if invalid, false if valid.
++ */
++static bool nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
+ {
+-      return offset < ((le64_to_cpu(sbp->s_nsegments) *
+-                        le32_to_cpu(sbp->s_blocks_per_segment)) <<
+-                       (le32_to_cpu(sbp->s_log_block_size) + 10));
++      unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size);
++      u32 blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
++      u64 nsegments = le64_to_cpu(sbp->s_nsegments);
++      u64 index;
++
++      if (blocks_per_segment < NILFS_SEG_MIN_BLOCKS ||
++          shift_bits > ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS)
++              return true;
++
++      index = offset >> (shift_bits + BLOCK_SIZE_BITS);
++      do_div(index, blocks_per_segment);
++      return index < nsegments;
+ }
+ static void nilfs_release_super_block(struct the_nilfs *nilfs)
+-- 
+2.35.1
+
diff --git a/queue-5.10/ntb_netdev-use-dev_kfree_skb_any-in-interrupt-contex.patch b/queue-5.10/ntb_netdev-use-dev_kfree_skb_any-in-interrupt-contex.patch
new file mode 100644 (file)
index 0000000..1b9f637
--- /dev/null
@@ -0,0 +1,73 @@
+From c255d6587c1a774638175a06eb26f80158625f7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 16:06:59 -0800
+Subject: ntb_netdev: Use dev_kfree_skb_any() in interrupt context
+
+From: Eric Pilmore <epilmore@gigaio.com>
+
+[ Upstream commit 5f7d78b2b12a9d561f48fa00bab29b40f4616dad ]
+
+TX/RX callback handlers (ntb_netdev_tx_handler(),
+ntb_netdev_rx_handler()) can be called in interrupt
+context via the DMA framework when the respective
+DMA operations have completed. As such, any calls
+by these routines to free skb's, should use the
+interrupt context safe dev_kfree_skb_any() function.
+
+Previously, these callback handlers would call the
+interrupt unsafe version of dev_kfree_skb(). This has
+not presented an issue on Intel IOAT DMA engines as
+that driver utilizes tasklets rather than a hard
+interrupt handler, like the AMD PTDMA DMA driver.
+On AMD systems, a kernel WARNING message is
+encountered, which is being issued from
+skb_release_head_state() due to in_hardirq()
+being true.
+
+Besides the user visible WARNING from the kernel,
+the other symptom of this bug was that TCP/IP performance
+across the ntb_netdev interface was very poor, i.e.
+approximately an order of magnitude below what was
+expected. With the repair to use dev_kfree_skb_any(),
+kernel WARNINGs from skb_release_head_state() ceased
+and TCP/IP performance, as measured by iperf, was on
+par with expected results, approximately 20 Gb/s on
+AMD Milan based server. Note that this performance
+is comparable with Intel based servers.
+
+Fixes: 765ccc7bc3d91 ("ntb_netdev: correct skb leak")
+Fixes: 548c237c0a997 ("net: Add support for NTB virtual ethernet device")
+Signed-off-by: Eric Pilmore <epilmore@gigaio.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20221209000659.8318-1-epilmore@gigaio.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ntb_netdev.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c
+index 1b7d588ff3c5..b701ee83e64a 100644
+--- a/drivers/net/ntb_netdev.c
++++ b/drivers/net/ntb_netdev.c
+@@ -137,7 +137,7 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
+ enqueue_again:
+       rc = ntb_transport_rx_enqueue(qp, skb, skb->data, ndev->mtu + ETH_HLEN);
+       if (rc) {
+-              dev_kfree_skb(skb);
++              dev_kfree_skb_any(skb);
+               ndev->stats.rx_errors++;
+               ndev->stats.rx_fifo_errors++;
+       }
+@@ -192,7 +192,7 @@ static void ntb_netdev_tx_handler(struct ntb_transport_qp *qp, void *qp_data,
+               ndev->stats.tx_aborted_errors++;
+       }
+-      dev_kfree_skb(skb);
++      dev_kfree_skb_any(skb);
+       if (ntb_transport_tx_free_entry(dev->qp) >= tx_start) {
+               /* Make sure anybody stopping the queue after this sees the new
+-- 
+2.35.1
+
diff --git a/queue-5.10/objtool-kcsan-add-volatile-read-write-instrumentatio.patch b/queue-5.10/objtool-kcsan-add-volatile-read-write-instrumentatio.patch
new file mode 100644 (file)
index 0000000..676bb7a
--- /dev/null
@@ -0,0 +1,49 @@
+From 9d0431861fa75e8b58bfdf8c606e2656d48d1180 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Sep 2022 11:45:41 +0200
+Subject: objtool, kcsan: Add volatile read/write instrumentation to whitelist
+
+From: Marco Elver <elver@google.com>
+
+[ Upstream commit 63646fcba5bb4b59a19031c21913f94e46a3d0d4 ]
+
+Adds KCSAN's volatile instrumentation to objtool's uaccess whitelist.
+
+Recent kernel change have shown that this was missing from the uaccess
+whitelist (since the first upstreamed version of KCSAN):
+
+  mm/gup.o: warning: objtool: fault_in_readable+0x101: call to __tsan_volatile_write1() with UACCESS enabled
+
+Fixes: 75d75b7a4d54 ("kcsan: Support distinguishing volatile accesses")
+Signed-off-by: Marco Elver <elver@google.com>
+Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/check.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index ea80b29b9913..5d64b673da2d 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -802,6 +802,16 @@ static const char *uaccess_safe_builtin[] = {
+       "__tsan_read_write4",
+       "__tsan_read_write8",
+       "__tsan_read_write16",
++      "__tsan_volatile_read1",
++      "__tsan_volatile_read2",
++      "__tsan_volatile_read4",
++      "__tsan_volatile_read8",
++      "__tsan_volatile_read16",
++      "__tsan_volatile_write1",
++      "__tsan_volatile_write2",
++      "__tsan_volatile_write4",
++      "__tsan_volatile_write8",
++      "__tsan_volatile_write16",
+       "__tsan_atomic8_load",
+       "__tsan_atomic16_load",
+       "__tsan_atomic32_load",
+-- 
+2.35.1
+
diff --git a/queue-5.10/ocfs2-fix-memory-leak-in-ocfs2_mount_volume.patch b/queue-5.10/ocfs2-fix-memory-leak-in-ocfs2_mount_volume.patch
new file mode 100644 (file)
index 0000000..59df18f
--- /dev/null
@@ -0,0 +1,121 @@
+From 80f3d7a1f5f8ee36854e226c9d1e1e452a755257 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 15:46:27 +0800
+Subject: ocfs2: fix memory leak in ocfs2_mount_volume()
+
+From: Li Zetao <ocfs2-devel@oss.oracle.com>
+
+[ Upstream commit ce2fcf1516d674a174d9b34d1e1024d64de9fba3 ]
+
+There is a memory leak reported by kmemleak:
+
+  unreferenced object 0xffff88810cc65e60 (size 32):
+    comm "mount.ocfs2", pid 23753, jiffies 4302528942 (age 34735.105s)
+    hex dump (first 32 bytes):
+      10 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01  ................
+      01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00  ................
+    backtrace:
+      [<ffffffff8170f73d>] __kmalloc+0x4d/0x150
+      [<ffffffffa0ac3f51>] ocfs2_compute_replay_slots+0x121/0x330 [ocfs2]
+      [<ffffffffa0b65165>] ocfs2_check_volume+0x485/0x900 [ocfs2]
+      [<ffffffffa0b68129>] ocfs2_mount_volume.isra.0+0x1e9/0x650 [ocfs2]
+      [<ffffffffa0b7160b>] ocfs2_fill_super+0xe0b/0x1740 [ocfs2]
+      [<ffffffff818e1fe2>] mount_bdev+0x312/0x400
+      [<ffffffff819a086d>] legacy_get_tree+0xed/0x1d0
+      [<ffffffff818de82d>] vfs_get_tree+0x7d/0x230
+      [<ffffffff81957f92>] path_mount+0xd62/0x1760
+      [<ffffffff81958a5a>] do_mount+0xca/0xe0
+      [<ffffffff81958d3c>] __x64_sys_mount+0x12c/0x1a0
+      [<ffffffff82f26f15>] do_syscall_64+0x35/0x80
+      [<ffffffff8300006a>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+This call stack is related to two problems.  Firstly, the ocfs2 super uses
+"replay_map" to trace online/offline slots, in order to recover offline
+slots during recovery and mount.  But when ocfs2_truncate_log_init()
+returns an error in ocfs2_mount_volume(), the memory of "replay_map" will
+not be freed in error handling path.  Secondly, the memory of "replay_map"
+will not be freed if d_make_root() returns an error in ocfs2_fill_super().
+But the memory of "replay_map" will be freed normally when completing
+recovery and mount in ocfs2_complete_mount_recovery().
+
+Fix the first problem by adding error handling path to free "replay_map"
+when ocfs2_truncate_log_init() fails.  And fix the second problem by
+calling ocfs2_free_replay_slots(osb) in the error handling path
+"out_dismount".  In addition, since ocfs2_free_replay_slots() is static,
+it is necessary to remove its static attribute and declare it in header
+file.
+
+Link: https://lkml.kernel.org/r/20221109074627.2303950-1-lizetao1@huawei.com
+Fixes: 9140db04ef18 ("ocfs2: recover orphans in offline slots during recovery and mount")
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Jun Piao <piaojun@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/journal.c | 2 +-
+ fs/ocfs2/journal.h | 1 +
+ fs/ocfs2/super.c   | 5 ++++-
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
+index db52e843002a..0534800a472a 100644
+--- a/fs/ocfs2/journal.c
++++ b/fs/ocfs2/journal.c
+@@ -159,7 +159,7 @@ static void ocfs2_queue_replay_slots(struct ocfs2_super *osb,
+       replay_map->rm_state = REPLAY_DONE;
+ }
+-static void ocfs2_free_replay_slots(struct ocfs2_super *osb)
++void ocfs2_free_replay_slots(struct ocfs2_super *osb)
+ {
+       struct ocfs2_replay_map *replay_map = osb->replay_map;
+diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
+index bfe611ed1b1d..eb7a21bac71e 100644
+--- a/fs/ocfs2/journal.h
++++ b/fs/ocfs2/journal.h
+@@ -152,6 +152,7 @@ int ocfs2_recovery_init(struct ocfs2_super *osb);
+ void ocfs2_recovery_exit(struct ocfs2_super *osb);
+ int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
++void ocfs2_free_replay_slots(struct ocfs2_super *osb);
+ /*
+  *  Journal Control:
+  *  Initialize, Load, Shutdown, Wipe a journal.
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
+index 72c44f7d7bd4..3e0b2e3e00ad 100644
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -1164,6 +1164,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+ out_dismount:
+       atomic_set(&osb->vol_state, VOLUME_DISABLED);
+       wake_up(&osb->osb_mount_event);
++      ocfs2_free_replay_slots(osb);
+       ocfs2_dismount_volume(sb, 1);
+       goto out;
+@@ -1829,12 +1830,14 @@ static int ocfs2_mount_volume(struct super_block *sb)
+       status = ocfs2_truncate_log_init(osb);
+       if (status < 0) {
+               mlog_errno(status);
+-              goto out_system_inodes;
++              goto out_check_volume;
+       }
+       ocfs2_super_unlock(osb, 1);
+       return 0;
++out_check_volume:
++      ocfs2_free_replay_slots(osb);
+ out_system_inodes:
+       if (osb->local_alloc_state == OCFS2_LA_ENABLED)
+               ocfs2_shutdown_local_alloc(osb);
+-- 
+2.35.1
+
diff --git a/queue-5.10/ocfs2-fix-memory-leak-in-ocfs2_stack_glue_init.patch b/queue-5.10/ocfs2-fix-memory-leak-in-ocfs2_stack_glue_init.patch
new file mode 100644 (file)
index 0000000..e90363e
--- /dev/null
@@ -0,0 +1,73 @@
+From 5fb2e927848cbd76e90c869ceaf5004833fae5bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 19:15:33 +0800
+Subject: ocfs2: fix memory leak in ocfs2_stack_glue_init()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit 13b6269dd022aaa69ca8d1df374ab327504121cf ]
+
+ocfs2_table_header should be free in ocfs2_stack_glue_init() if
+ocfs2_sysfs_init() failed, otherwise kmemleak will report memleak.
+
+BUG: memory leak
+unreferenced object 0xffff88810eeb5800 (size 128):
+  comm "modprobe", pid 4507, jiffies 4296182506 (age 55.888s)
+  hex dump (first 32 bytes):
+    c0 40 14 a0 ff ff ff ff 00 00 00 00 01 00 00 00  .@..............
+    01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+  backtrace:
+    [<000000001e59e1cd>] __register_sysctl_table+0xca/0xef0
+    [<00000000c04f70f7>] 0xffffffffa0050037
+    [<000000001bd12912>] do_one_initcall+0xdb/0x480
+    [<0000000064f766c9>] do_init_module+0x1cf/0x680
+    [<000000002ba52db0>] load_module+0x6441/0x6f20
+    [<000000009772580d>] __do_sys_finit_module+0x12f/0x1c0
+    [<00000000380c1f22>] do_syscall_64+0x3f/0x90
+    [<000000004cf473bc>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Link: https://lkml.kernel.org/r/41651ca1-432a-db34-eb97-d35744559de1@linux.alibaba.com
+Fixes: 3878f110f71a ("ocfs2: Move the hb_ctl_path sysctl into the stack glue.")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Jun Piao <piaojun@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/stackglue.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
+index 03eacb249f37..5e272e257b0b 100644
+--- a/fs/ocfs2/stackglue.c
++++ b/fs/ocfs2/stackglue.c
+@@ -705,6 +705,8 @@ static struct ctl_table_header *ocfs2_table_header;
+ static int __init ocfs2_stack_glue_init(void)
+ {
++      int ret;
++
+       strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB);
+       ocfs2_table_header = register_sysctl_table(ocfs2_root_table);
+@@ -714,7 +716,11 @@ static int __init ocfs2_stack_glue_init(void)
+               return -ENOMEM; /* or something. */
+       }
+-      return ocfs2_sysfs_init();
++      ret = ocfs2_sysfs_init();
++      if (ret)
++              unregister_sysctl_table(ocfs2_table_header);
++
++      return ret;
+ }
+ static void __exit ocfs2_stack_glue_exit(void)
+-- 
+2.35.1
+
diff --git a/queue-5.10/ocfs2-ocfs2_mount_volume-does-cleanup-job-before-ret.patch b/queue-5.10/ocfs2-ocfs2_mount_volume-does-cleanup-job-before-ret.patch
new file mode 100644 (file)
index 0000000..ca35180
--- /dev/null
@@ -0,0 +1,115 @@
+From a8d92e3c8f5227ad605c9980bee552fe5ebbf9fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Apr 2022 14:37:58 -0700
+Subject: ocfs2: ocfs2_mount_volume does cleanup job before return error
+
+From: Heming Zhao via Ocfs2-devel <ocfs2-devel@oss.oracle.com>
+
+[ Upstream commit 0737e01de9c411e4db87dcedf4a9789d41b1c5c1 ]
+
+After this patch, when error, ocfs2_fill_super doesn't take care to
+release resources which are allocated in ocfs2_mount_volume.
+
+Link: https://lkml.kernel.org/r/20220424130952.2436-5-heming.zhao@suse.com
+Signed-off-by: Heming Zhao <heming.zhao@suse.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: ce2fcf1516d6 ("ocfs2: fix memory leak in ocfs2_mount_volume()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/super.c | 35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
+index c0e5f1bad499..ca0d6debae97 100644
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -1787,11 +1787,10 @@ static int ocfs2_get_sector(struct super_block *sb,
+ static int ocfs2_mount_volume(struct super_block *sb)
+ {
+       int status = 0;
+-      int unlock_super = 0;
+       struct ocfs2_super *osb = OCFS2_SB(sb);
+       if (ocfs2_is_hard_readonly(osb))
+-              goto leave;
++              goto out;
+       mutex_init(&osb->obs_trim_fs_mutex);
+@@ -1801,44 +1800,56 @@ static int ocfs2_mount_volume(struct super_block *sb)
+               if (status == -EBADR && ocfs2_userspace_stack(osb))
+                       mlog(ML_ERROR, "couldn't mount because cluster name on"
+                       " disk does not match the running cluster name.\n");
+-              goto leave;
++              goto out;
+       }
+       status = ocfs2_super_lock(osb, 1);
+       if (status < 0) {
+               mlog_errno(status);
+-              goto leave;
++              goto out_dlm;
+       }
+-      unlock_super = 1;
+       /* This will load up the node map and add ourselves to it. */
+       status = ocfs2_find_slot(osb);
+       if (status < 0) {
+               mlog_errno(status);
+-              goto leave;
++              goto out_super_lock;
+       }
+       /* load all node-local system inodes */
+       status = ocfs2_init_local_system_inodes(osb);
+       if (status < 0) {
+               mlog_errno(status);
+-              goto leave;
++              goto out_super_lock;
+       }
+       status = ocfs2_check_volume(osb);
+       if (status < 0) {
+               mlog_errno(status);
+-              goto leave;
++              goto out_system_inodes;
+       }
+       status = ocfs2_truncate_log_init(osb);
+-      if (status < 0)
++      if (status < 0) {
+               mlog_errno(status);
++              goto out_system_inodes;
++      }
+-leave:
+-      if (unlock_super)
+-              ocfs2_super_unlock(osb, 1);
++      ocfs2_super_unlock(osb, 1);
++      return 0;
++out_system_inodes:
++      if (osb->local_alloc_state == OCFS2_LA_ENABLED)
++              ocfs2_shutdown_local_alloc(osb);
++      ocfs2_release_system_inodes(osb);
++      /* before journal shutdown, we should release slot_info */
++      ocfs2_free_slot_info(osb);
++      ocfs2_journal_shutdown(osb);
++out_super_lock:
++      ocfs2_super_unlock(osb, 1);
++out_dlm:
++      ocfs2_dlm_shutdown(osb, 0);
++out:
+       return status;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/ocfs2-rewrite-error-handling-of-ocfs2_fill_super.patch b/queue-5.10/ocfs2-rewrite-error-handling-of-ocfs2_fill_super.patch
new file mode 100644 (file)
index 0000000..2c6d410
--- /dev/null
@@ -0,0 +1,200 @@
+From ddd665f713d7641ef41b67be2657f4e826c8aac7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Apr 2022 14:37:58 -0700
+Subject: ocfs2: rewrite error handling of ocfs2_fill_super
+
+From: Heming Zhao via Ocfs2-devel <ocfs2-devel@oss.oracle.com>
+
+[ Upstream commit f1e75d128b46e3b066e7b2e7cfca10491109d44d ]
+
+Current ocfs2_fill_super() uses one goto label "read_super_error" to
+handle all error cases.  And with previous serial patches, the error
+handling should fork more branches to handle different error cases.  This
+patch rewrite the error handling of ocfs2_fill_super.
+
+Link: https://lkml.kernel.org/r/20220424130952.2436-6-heming.zhao@suse.com
+Signed-off-by: Heming Zhao <heming.zhao@suse.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: ce2fcf1516d6 ("ocfs2: fix memory leak in ocfs2_mount_volume()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/super.c | 67 +++++++++++++++++++++++-------------------------
+ 1 file changed, 32 insertions(+), 35 deletions(-)
+
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
+index ca0d6debae97..72c44f7d7bd4 100644
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -984,28 +984,27 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) {
+               status = -EINVAL;
+-              goto read_super_error;
++              goto out;
+       }
+       /* probe for superblock */
+       status = ocfs2_sb_probe(sb, &bh, &sector_size, &stats);
+       if (status < 0) {
+               mlog(ML_ERROR, "superblock probe failed!\n");
+-              goto read_super_error;
++              goto out;
+       }
+       status = ocfs2_initialize_super(sb, bh, sector_size, &stats);
+-      osb = OCFS2_SB(sb);
+-      if (status < 0) {
+-              mlog_errno(status);
+-              goto read_super_error;
+-      }
+       brelse(bh);
+       bh = NULL;
++      if (status < 0)
++              goto out;
++
++      osb = OCFS2_SB(sb);
+       if (!ocfs2_check_set_options(sb, &parsed_options)) {
+               status = -EINVAL;
+-              goto read_super_error;
++              goto out_super;
+       }
+       osb->s_mount_opt = parsed_options.mount_opt;
+       osb->s_atime_quantum = parsed_options.atime_quantum;
+@@ -1022,7 +1021,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       status = ocfs2_verify_userspace_stack(osb, &parsed_options);
+       if (status)
+-              goto read_super_error;
++              goto out_super;
+       sb->s_magic = OCFS2_SUPER_MAGIC;
+@@ -1036,7 +1035,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+                       status = -EACCES;
+                       mlog(ML_ERROR, "Readonly device detected but readonly "
+                            "mount was not specified.\n");
+-                      goto read_super_error;
++                      goto out_super;
+               }
+               /* You should not be able to start a local heartbeat
+@@ -1045,7 +1044,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+                       status = -EROFS;
+                       mlog(ML_ERROR, "Local heartbeat specified on readonly "
+                            "device.\n");
+-                      goto read_super_error;
++                      goto out_super;
+               }
+               status = ocfs2_check_journals_nolocks(osb);
+@@ -1054,9 +1053,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+                               mlog(ML_ERROR, "Recovery required on readonly "
+                                    "file system, but write access is "
+                                    "unavailable.\n");
+-                      else
+-                              mlog_errno(status);
+-                      goto read_super_error;
++                      goto out_super;
+               }
+               ocfs2_set_ro_flag(osb, 1);
+@@ -1072,10 +1069,8 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       }
+       status = ocfs2_verify_heartbeat(osb);
+-      if (status < 0) {
+-              mlog_errno(status);
+-              goto read_super_error;
+-      }
++      if (status < 0)
++              goto out_super;
+       osb->osb_debug_root = debugfs_create_dir(osb->uuid_str,
+                                                ocfs2_debugfs_root);
+@@ -1089,15 +1084,14 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       status = ocfs2_mount_volume(sb);
+       if (status < 0)
+-              goto read_super_error;
++              goto out_debugfs;
+       if (osb->root_inode)
+               inode = igrab(osb->root_inode);
+       if (!inode) {
+               status = -EIO;
+-              mlog_errno(status);
+-              goto read_super_error;
++              goto out_dismount;
+       }
+       osb->osb_dev_kset = kset_create_and_add(sb->s_id, NULL,
+@@ -1105,7 +1099,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       if (!osb->osb_dev_kset) {
+               status = -ENOMEM;
+               mlog(ML_ERROR, "Unable to create device kset %s.\n", sb->s_id);
+-              goto read_super_error;
++              goto out_dismount;
+       }
+       /* Create filecheck sysfs related directories/files at
+@@ -1114,14 +1108,13 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+               status = -ENOMEM;
+               mlog(ML_ERROR, "Unable to create filecheck sysfs directory at "
+                       "/sys/fs/ocfs2/%s/filecheck.\n", sb->s_id);
+-              goto read_super_error;
++              goto out_dismount;
+       }
+       root = d_make_root(inode);
+       if (!root) {
+               status = -ENOMEM;
+-              mlog_errno(status);
+-              goto read_super_error;
++              goto out_dismount;
+       }
+       sb->s_root = root;
+@@ -1168,17 +1161,21 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       return status;
+-read_super_error:
+-      brelse(bh);
+-
+-      if (status)
+-              mlog_errno(status);
++out_dismount:
++      atomic_set(&osb->vol_state, VOLUME_DISABLED);
++      wake_up(&osb->osb_mount_event);
++      ocfs2_dismount_volume(sb, 1);
++      goto out;
+-      if (osb) {
+-              atomic_set(&osb->vol_state, VOLUME_DISABLED);
+-              wake_up(&osb->osb_mount_event);
+-              ocfs2_dismount_volume(sb, 1);
+-      }
++out_debugfs:
++      debugfs_remove_recursive(osb->osb_debug_root);
++out_super:
++      ocfs2_release_system_inodes(osb);
++      kfree(osb->recovery_map);
++      ocfs2_delete_osb(osb);
++      kfree(osb);
++out:
++      mlog_errno(status);
+       return status;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/ocxl-fix-pci-device-refcount-leak-when-calling-get_f.patch b/queue-5.10/ocxl-fix-pci-device-refcount-leak-when-calling-get_f.patch
new file mode 100644 (file)
index 0000000..ab187ee
--- /dev/null
@@ -0,0 +1,87 @@
+From 45eeb4d7e22d9ac7be42229665b3b00245ab1cb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 23:43:39 +0800
+Subject: ocxl: fix pci device refcount leak when calling get_function_0()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 27158c72678b39ee01cc01de1aba6b51c71abe2f ]
+
+get_function_0() calls pci_get_domain_bus_and_slot(), as comment
+says, it returns a pci device with refcount increment, so after
+using it, pci_dev_put() needs be called.
+
+Get the device reference when get_function_0() is not called, so
+pci_dev_put() can be called in the error path and callers
+unconditionally. And add comment above get_dvsec_vendor0() to tell
+callers to call pci_dev_put().
+
+Fixes: 87db7579ebd5 ("ocxl: control via sysfs whether the FPGA is reloaded on a link reset")
+Suggested-by: Andrew Donnellan <ajd@linux.ibm.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: Andrew Donnellan <ajd@linux.ibm.com>
+Link: https://lore.kernel.org/r/20221121154339.4088935-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/ocxl/config.c | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
+index 4d490b92d951..3ced98b506f4 100644
+--- a/drivers/misc/ocxl/config.c
++++ b/drivers/misc/ocxl/config.c
+@@ -204,6 +204,18 @@ static int read_dvsec_vendor(struct pci_dev *dev)
+       return 0;
+ }
++/**
++ * get_dvsec_vendor0() - Find a related PCI device (function 0)
++ * @dev: PCI device to match
++ * @dev0: The PCI device (function 0) found
++ * @out_pos: The position of PCI device (function 0)
++ *
++ * Returns 0 on success, negative on failure.
++ *
++ * NOTE: If it's successful, the reference of dev0 is increased,
++ * so after using it, the callers must call pci_dev_put() to give
++ * up the reference.
++ */
+ static int get_dvsec_vendor0(struct pci_dev *dev, struct pci_dev **dev0,
+                            int *out_pos)
+ {
+@@ -213,10 +225,14 @@ static int get_dvsec_vendor0(struct pci_dev *dev, struct pci_dev **dev0,
+               dev = get_function_0(dev);
+               if (!dev)
+                       return -1;
++      } else {
++              dev = pci_dev_get(dev);
+       }
+       pos = find_dvsec(dev, OCXL_DVSEC_VENDOR_ID);
+-      if (!pos)
++      if (!pos) {
++              pci_dev_put(dev);
+               return -1;
++      }
+       *dev0 = dev;
+       *out_pos = pos;
+       return 0;
+@@ -233,6 +249,7 @@ int ocxl_config_get_reset_reload(struct pci_dev *dev, int *val)
+       pci_read_config_dword(dev0, pos + OCXL_DVSEC_VENDOR_RESET_RELOAD,
+                             &reset_reload);
++      pci_dev_put(dev0);
+       *val = !!(reset_reload & BIT(0));
+       return 0;
+ }
+@@ -254,6 +271,7 @@ int ocxl_config_set_reset_reload(struct pci_dev *dev, int val)
+               reset_reload &= ~BIT(0);
+       pci_write_config_dword(dev0, pos + OCXL_DVSEC_VENDOR_RESET_RELOAD,
+                              reset_reload);
++      pci_dev_put(dev0);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/of-overlay-fix-null-pointer-dereferencing-in-find_du.patch b/queue-5.10/of-overlay-fix-null-pointer-dereferencing-in-find_du.patch
new file mode 100644 (file)
index 0000000..f46c09d
--- /dev/null
@@ -0,0 +1,47 @@
+From 4037e9bd06e550ab5398144afee043975c742ab5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Dec 2022 10:33:37 +0800
+Subject: of: overlay: fix null pointer dereferencing in
+ find_dup_cset_node_entry() and find_dup_cset_prop()
+
+From: ruanjinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit ee9d7a0e754568180a2f8ebc4aad226278a9116f ]
+
+When kmalloc() fail to allocate memory in kasprintf(), fn_1 or fn_2 will
+be NULL, and strcmp() will cause null pointer dereference.
+
+Fixes: 2fe0e8769df9 ("of: overlay: check prevents multiple fragments touching same property")
+Signed-off-by: ruanjinjie <ruanjinjie@huawei.com>
+Link: https://lore.kernel.org/r/20221211023337.592266-1-ruanjinjie@huawei.com
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/overlay.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
+index c8a0c0e9dec1..67b404f36e79 100644
+--- a/drivers/of/overlay.c
++++ b/drivers/of/overlay.c
+@@ -547,7 +547,7 @@ static int find_dup_cset_node_entry(struct overlay_changeset *ovcs,
+               fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
+               fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
+-              node_path_match = !strcmp(fn_1, fn_2);
++              node_path_match = !fn_1 || !fn_2 || !strcmp(fn_1, fn_2);
+               kfree(fn_1);
+               kfree(fn_2);
+               if (node_path_match) {
+@@ -582,7 +582,7 @@ static int find_dup_cset_prop(struct overlay_changeset *ovcs,
+               fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
+               fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
+-              node_path_match = !strcmp(fn_1, fn_2);
++              node_path_match = !fn_1 || !fn_2 || !strcmp(fn_1, fn_2);
+               kfree(fn_1);
+               kfree(fn_2);
+               if (node_path_match &&
+-- 
+2.35.1
+
diff --git a/queue-5.10/openvswitch-fix-flow-lookup-to-use-unmasked-key.patch b/queue-5.10/openvswitch-fix-flow-lookup-to-use-unmasked-key.patch
new file mode 100644 (file)
index 0000000..d9e2ad0
--- /dev/null
@@ -0,0 +1,121 @@
+From 8dd6fb5a60b2dcba4db11b5e262e2780decc2077 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Dec 2022 15:46:33 +0100
+Subject: openvswitch: Fix flow lookup to use unmasked key
+
+From: Eelco Chaudron <echaudro@redhat.com>
+
+[ Upstream commit 68bb10101e6b0a6bb44e9c908ef795fc4af99eae ]
+
+The commit mentioned below causes the ovs_flow_tbl_lookup() function
+to be called with the masked key. However, it's supposed to be called
+with the unmasked key. This due to the fact that the datapath supports
+installing wider flows, and OVS relies on this behavior. For example
+if ipv4(src=1.1.1.1/192.0.0.0, dst=1.1.1.2/192.0.0.0) exists, a wider
+flow (smaller mask) of ipv4(src=192.1.1.1/128.0.0.0,dst=192.1.1.2/
+128.0.0.0) is allowed to be added.
+
+However, if we try to add a wildcard rule, the installation fails:
+
+$ ovs-appctl dpctl/add-flow system@myDP "in_port(1),eth_type(0x0800), \
+  ipv4(src=1.1.1.1/192.0.0.0,dst=1.1.1.2/192.0.0.0,frag=no)" 2
+$ ovs-appctl dpctl/add-flow system@myDP "in_port(1),eth_type(0x0800), \
+  ipv4(src=192.1.1.1/0.0.0.0,dst=49.1.1.2/0.0.0.0,frag=no)" 2
+ovs-vswitchd: updating flow table (File exists)
+
+The reason is that the key used to determine if the flow is already
+present in the system uses the original key ANDed with the mask.
+This results in the IP address not being part of the (miniflow) key,
+i.e., being substituted with an all-zero value. When doing the actual
+lookup, this results in the key wrongfully matching the first flow,
+and therefore the flow does not get installed.
+
+This change reverses the commit below, but rather than having the key
+on the stack, it's allocated.
+
+Fixes: 190aa3e77880 ("openvswitch: Fix Frame-size larger than 1024 bytes warning.")
+
+Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/datapath.c | 25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 7ed97dc0b561..435f7f1be614 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -933,6 +933,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+       struct sw_flow_mask mask;
+       struct sk_buff *reply;
+       struct datapath *dp;
++      struct sw_flow_key *key;
+       struct sw_flow_actions *acts;
+       struct sw_flow_match match;
+       u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
+@@ -960,24 +961,26 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+       }
+       /* Extract key. */
+-      ovs_match_init(&match, &new_flow->key, false, &mask);
++      key = kzalloc(sizeof(*key), GFP_KERNEL);
++      if (!key) {
++              error = -ENOMEM;
++              goto err_kfree_key;
++      }
++
++      ovs_match_init(&match, key, false, &mask);
+       error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
+                                 a[OVS_FLOW_ATTR_MASK], log);
+       if (error)
+               goto err_kfree_flow;
++      ovs_flow_mask_key(&new_flow->key, key, true, &mask);
++
+       /* Extract flow identifier. */
+       error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
+-                                     &new_flow->key, log);
++                                     key, log);
+       if (error)
+               goto err_kfree_flow;
+-      /* unmasked key is needed to match when ufid is not used. */
+-      if (ovs_identifier_is_key(&new_flow->id))
+-              match.key = new_flow->id.unmasked_key;
+-
+-      ovs_flow_mask_key(&new_flow->key, &new_flow->key, true, &mask);
+-
+       /* Validate actions. */
+       error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS],
+                                    &new_flow->key, &acts, log);
+@@ -1004,7 +1007,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+       if (ovs_identifier_is_ufid(&new_flow->id))
+               flow = ovs_flow_tbl_lookup_ufid(&dp->table, &new_flow->id);
+       if (!flow)
+-              flow = ovs_flow_tbl_lookup(&dp->table, &new_flow->key);
++              flow = ovs_flow_tbl_lookup(&dp->table, key);
+       if (likely(!flow)) {
+               rcu_assign_pointer(new_flow->sf_acts, acts);
+@@ -1074,6 +1077,8 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+       if (reply)
+               ovs_notify(&dp_flow_genl_family, reply, info);
++
++      kfree(key);
+       return 0;
+ err_unlock_ovs:
+@@ -1083,6 +1088,8 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+       ovs_nla_free_flow_actions(acts);
+ err_kfree_flow:
+       ovs_flow_free(new_flow, false);
++err_kfree_key:
++      kfree(key);
+ error:
+       return error;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/orangefs-fix-kmemleak-in-orangefs_-kernel-client-_de.patch b/queue-5.10/orangefs-fix-kmemleak-in-orangefs_-kernel-client-_de.patch
new file mode 100644 (file)
index 0000000..16dc481
--- /dev/null
@@ -0,0 +1,107 @@
+From 1ebd309954c58593d5a21f7dee7f49a593626a12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 12:40:07 +0800
+Subject: orangefs: Fix kmemleak in orangefs_{kernel,client}_debug_init()
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+[ Upstream commit 31720a2b109b3080eb77e97b8f6f50a27b4ae599 ]
+
+When insert and remove the orangefs module, there are memory leaked
+as below:
+
+unreferenced object 0xffff88816b0cc000 (size 2048):
+  comm "insmod", pid 783, jiffies 4294813439 (age 65.512s)
+  hex dump (first 32 bytes):
+    6e 6f 6e 65 0a 00 00 00 00 00 00 00 00 00 00 00  none............
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+  backtrace:
+    [<0000000031ab7788>] kmalloc_trace+0x27/0xa0
+    [<000000005b405fee>] orangefs_debugfs_init.cold+0xaf/0x17f
+    [<00000000e5a0085b>] 0xffffffffa02780f9
+    [<000000004232d9f7>] do_one_initcall+0x87/0x2a0
+    [<0000000054f22384>] do_init_module+0xdf/0x320
+    [<000000003263bdea>] load_module+0x2f98/0x3330
+    [<0000000052cd4153>] __do_sys_finit_module+0x113/0x1b0
+    [<00000000250ae02b>] do_syscall_64+0x35/0x80
+    [<00000000f11c03c7>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+Use the golbal variable as the buffer rather than dynamic allocate to
+slove the problem.
+
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Signed-off-by: Mike Marshall <hubcap@omnibond.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/orangefs/orangefs-debugfs.c | 26 +++-----------------------
+ 1 file changed, 3 insertions(+), 23 deletions(-)
+
+diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c
+index a848b6ef9599..1b508f543384 100644
+--- a/fs/orangefs/orangefs-debugfs.c
++++ b/fs/orangefs/orangefs-debugfs.c
+@@ -194,15 +194,10 @@ void orangefs_debugfs_init(int debug_mask)
+  */
+ static void orangefs_kernel_debug_init(void)
+ {
+-      int rc = -ENOMEM;
+-      char *k_buffer = NULL;
++      static char k_buffer[ORANGEFS_MAX_DEBUG_STRING_LEN] = { };
+       gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__);
+-      k_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
+-      if (!k_buffer)
+-              goto out;
+-
+       if (strlen(kernel_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) {
+               strcpy(k_buffer, kernel_debug_string);
+               strcat(k_buffer, "\n");
+@@ -213,9 +208,6 @@ static void orangefs_kernel_debug_init(void)
+       debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE, 0444, debug_dir, k_buffer,
+                           &kernel_debug_fops);
+-
+-out:
+-      gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc);
+ }
+@@ -299,18 +291,13 @@ static int help_show(struct seq_file *m, void *v)
+ /*
+  * initialize the client-debug file.
+  */
+-static int orangefs_client_debug_init(void)
++static void orangefs_client_debug_init(void)
+ {
+-      int rc = -ENOMEM;
+-      char *c_buffer = NULL;
++      static char c_buffer[ORANGEFS_MAX_DEBUG_STRING_LEN] = { };
+       gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__);
+-      c_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
+-      if (!c_buffer)
+-              goto out;
+-
+       if (strlen(client_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) {
+               strcpy(c_buffer, client_debug_string);
+               strcat(c_buffer, "\n");
+@@ -324,13 +311,6 @@ static int orangefs_client_debug_init(void)
+                                                 debug_dir,
+                                                 c_buffer,
+                                                 &kernel_debug_fops);
+-
+-      rc = 0;
+-
+-out:
+-
+-      gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc);
+-      return rc;
+ }
+ /* open ORANGEFS_KMOD_DEBUG_FILE or ORANGEFS_CLIENT_DEBUG_FILE.*/
+-- 
+2.35.1
+
diff --git a/queue-5.10/orangefs-fix-kmemleak-in-orangefs_prepare_debugfs_he.patch b/queue-5.10/orangefs-fix-kmemleak-in-orangefs_prepare_debugfs_he.patch
new file mode 100644 (file)
index 0000000..dfca123
--- /dev/null
@@ -0,0 +1,62 @@
+From 6607d348acc792f91d6aca4f371c623b4e4320a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 12:40:05 +0800
+Subject: orangefs: Fix kmemleak in orangefs_prepare_debugfs_help_string()
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+[ Upstream commit d23417a5bf3a3afc55de5442eb46e1e60458b0a1 ]
+
+When insert and remove the orangefs module, then debug_help_string will
+be leaked:
+
+  unreferenced object 0xffff8881652ba000 (size 4096):
+    comm "insmod", pid 1701, jiffies 4294893639 (age 13218.530s)
+    hex dump (first 32 bytes):
+      43 6c 69 65 6e 74 20 44 65 62 75 67 20 4b 65 79  Client Debug Key
+      77 6f 72 64 73 20 61 72 65 20 75 6e 6b 6e 6f 77  words are unknow
+    backtrace:
+      [<0000000004e6f8e3>] kmalloc_trace+0x27/0xa0
+      [<0000000006f75d85>] orangefs_prepare_debugfs_help_string+0x5e/0x480 [orangefs]
+      [<0000000091270a2a>] _sub_I_65535_1+0x57/0xf70 [crc_itu_t]
+      [<000000004b1ee1a3>] do_one_initcall+0x87/0x2a0
+      [<000000001d0614ae>] do_init_module+0xdf/0x320
+      [<00000000efef068c>] load_module+0x2f98/0x3330
+      [<000000006533b44d>] __do_sys_finit_module+0x113/0x1b0
+      [<00000000a0da6f99>] do_syscall_64+0x35/0x80
+      [<000000007790b19b>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+When remove the module, should always free debug_help_string. Should
+always free the allocated buffer when change the free_debug_help_string.
+
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Signed-off-by: Mike Marshall <hubcap@omnibond.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/orangefs/orangefs-debugfs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c
+index 29eaa4544372..a848b6ef9599 100644
+--- a/fs/orangefs/orangefs-debugfs.c
++++ b/fs/orangefs/orangefs-debugfs.c
+@@ -222,6 +222,8 @@ static void orangefs_kernel_debug_init(void)
+ void orangefs_debugfs_cleanup(void)
+ {
+       debugfs_remove_recursive(debug_dir);
++      kfree(debug_help_string);
++      debug_help_string = NULL;
+ }
+ /* open ORANGEFS_KMOD_DEBUG_HELP_FILE */
+@@ -671,6 +673,7 @@ int orangefs_prepare_debugfs_help_string(int at_boot)
+               memset(debug_help_string, 0, DEBUG_HELP_STRING_SIZE);
+               strlcat(debug_help_string, new, string_size);
+               mutex_unlock(&orangefs_help_file_lock);
++              kfree(new);
+       }
+       rc = 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/orangefs-fix-sysfs-not-cleanup-when-dev-init-failed.patch b/queue-5.10/orangefs-fix-sysfs-not-cleanup-when-dev-init-failed.patch
new file mode 100644 (file)
index 0000000..f62bee2
--- /dev/null
@@ -0,0 +1,74 @@
+From b5d9226f210e57bc5af4b4a98fe04274c815d66a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 12:40:04 +0800
+Subject: orangefs: Fix sysfs not cleanup when dev init failed
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+[ Upstream commit ea60a4ad0cf88b411cde6888b8c890935686ecd7 ]
+
+When the dev init failed, should cleanup the sysfs, otherwise, the
+module will never be loaded since can not create duplicate sysfs
+directory:
+
+  sysfs: cannot create duplicate filename '/fs/orangefs'
+
+  CPU: 1 PID: 6549 Comm: insmod Tainted: G        W          6.0.0+ #44
+  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014
+  Call Trace:
+   <TASK>
+   dump_stack_lvl+0x34/0x44
+   sysfs_warn_dup.cold+0x17/0x24
+   sysfs_create_dir_ns+0x16d/0x180
+   kobject_add_internal+0x156/0x3a0
+   kobject_init_and_add+0xcf/0x120
+   orangefs_sysfs_init+0x7e/0x3a0 [orangefs]
+   orangefs_init+0xfe/0x1000 [orangefs]
+   do_one_initcall+0x87/0x2a0
+   do_init_module+0xdf/0x320
+   load_module+0x2f98/0x3330
+   __do_sys_finit_module+0x113/0x1b0
+   do_syscall_64+0x35/0x80
+   entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+  kobject_add_internal failed for orangefs with -EEXIST, don't try to register things with the same name in the same directory.
+
+Fixes: 2f83ace37181 ("orangefs: put register_chrdev immediately before register_filesystem")
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Signed-off-by: Mike Marshall <hubcap@omnibond.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/orangefs/orangefs-mod.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c
+index 74a3d6337ef4..ac9c91b83868 100644
+--- a/fs/orangefs/orangefs-mod.c
++++ b/fs/orangefs/orangefs-mod.c
+@@ -141,7 +141,7 @@ static int __init orangefs_init(void)
+               gossip_err("%s: could not initialize device subsystem %d!\n",
+                          __func__,
+                          ret);
+-              goto cleanup_device;
++              goto cleanup_sysfs;
+       }
+       ret = register_filesystem(&orangefs_fs_type);
+@@ -152,11 +152,11 @@ static int __init orangefs_init(void)
+               goto out;
+       }
+-      orangefs_sysfs_exit();
+-
+-cleanup_device:
+       orangefs_dev_cleanup();
++cleanup_sysfs:
++      orangefs_sysfs_exit();
++
+ sysfs_init_failed:
+       orangefs_debugfs_cleanup();
+-- 
+2.35.1
+
diff --git a/queue-5.10/padata-always-leave-bhs-disabled-when-running-parall.patch b/queue-5.10/padata-always-leave-bhs-disabled-when-running-parall.patch
new file mode 100644 (file)
index 0000000..faefd12
--- /dev/null
@@ -0,0 +1,65 @@
+From f486ed3cb05d380529f581152caf82f75759454c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 20:28:02 -0500
+Subject: padata: Always leave BHs disabled when running ->parallel()
+
+From: Daniel Jordan <daniel.m.jordan@oracle.com>
+
+[ Upstream commit 34c3a47d20ae55b3600fed733bf96eafe9c500d5 ]
+
+A deadlock can happen when an overloaded system runs ->parallel() in the
+context of the current task:
+
+    padata_do_parallel
+      ->parallel()
+        pcrypt_aead_enc/dec
+          padata_do_serial
+            spin_lock(&reorder->lock) // BHs still enabled
+              <interrupt>
+                ...
+                  __do_softirq
+                    ...
+                      padata_do_serial
+                        spin_lock(&reorder->lock)
+
+It's a bug for BHs to be on in _do_serial as Steffen points out, so
+ensure they're off in the "current task" case like they are in
+padata_parallel_worker to avoid this situation.
+
+Reported-by: syzbot+bc05445bc14148d51915@syzkaller.appspotmail.com
+Fixes: 4611ce224688 ("padata: allocate work structures for parallel jobs from a pool")
+Signed-off-by: Daniel Jordan <daniel.m.jordan@oracle.com>
+Acked-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/padata.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/padata.c b/kernel/padata.c
+index d4d3ba6e1728..4d31a69a9b38 100644
+--- a/kernel/padata.c
++++ b/kernel/padata.c
+@@ -220,14 +220,16 @@ int padata_do_parallel(struct padata_shell *ps,
+       pw = padata_work_alloc();
+       spin_unlock(&padata_works_lock);
++      if (!pw) {
++              /* Maximum works limit exceeded, run in the current task. */
++              padata->parallel(padata);
++      }
++
+       rcu_read_unlock_bh();
+       if (pw) {
+               padata_work_init(pw, padata_parallel_worker, padata, 0);
+               queue_work(pinst->parallel_wq, &pw->pw_work);
+-      } else {
+-              /* Maximum works limit exceeded, run in the current task. */
+-              padata->parallel(padata);
+       }
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/padata-fix-list-iterator-in-padata_do_serial.patch b/queue-5.10/padata-fix-list-iterator-in-padata_do_serial.patch
new file mode 100644 (file)
index 0000000..4933f68
--- /dev/null
@@ -0,0 +1,51 @@
+From 2ffb5970f09a59f17224a64bb18e64e9296e8bd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 20:28:04 -0500
+Subject: padata: Fix list iterator in padata_do_serial()
+
+From: Daniel Jordan <daniel.m.jordan@oracle.com>
+
+[ Upstream commit 57ddfecc72a6c9941d159543e1c0c0a74fe9afdd ]
+
+list_for_each_entry_reverse() assumes that the iterated list is nonempty
+and that every list_head is embedded in the same type, but its use in
+padata_do_serial() breaks both rules.
+
+This doesn't cause any issues now because padata_priv and padata_list
+happen to have their list fields at the same offset, but we really
+shouldn't be relying on that.
+
+Fixes: bfde23ce200e ("padata: unbind parallel jobs from specific CPUs")
+Signed-off-by: Daniel Jordan <daniel.m.jordan@oracle.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/padata.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/padata.c b/kernel/padata.c
+index 4d31a69a9b38..11ca3ebd8b12 100644
+--- a/kernel/padata.c
++++ b/kernel/padata.c
+@@ -403,13 +403,16 @@ void padata_do_serial(struct padata_priv *padata)
+       int hashed_cpu = padata_cpu_hash(pd, padata->seq_nr);
+       struct padata_list *reorder = per_cpu_ptr(pd->reorder_list, hashed_cpu);
+       struct padata_priv *cur;
++      struct list_head *pos;
+       spin_lock(&reorder->lock);
+       /* Sort in ascending order of sequence number. */
+-      list_for_each_entry_reverse(cur, &reorder->list, list)
++      list_for_each_prev(pos, &reorder->list) {
++              cur = list_entry(pos, struct padata_priv, list);
+               if (cur->seq_nr < padata->seq_nr)
+                       break;
+-      list_add(&padata->list, &cur->list);
++      }
++      list_add(&padata->list, pos);
+       spin_unlock(&reorder->lock);
+       /*
+-- 
+2.35.1
+
diff --git a/queue-5.10/pata_ipx4xx_cf-fix-unsigned-comparison-with-less-tha.patch b/queue-5.10/pata_ipx4xx_cf-fix-unsigned-comparison-with-less-tha.patch
new file mode 100644 (file)
index 0000000..bf204fc
--- /dev/null
@@ -0,0 +1,46 @@
+From 13e4bd7cf737580d17591295b134420498b8a91a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Apr 2021 21:54:26 +0800
+Subject: pata_ipx4xx_cf: Fix unsigned comparison with less than zero
+
+From: Junlin Yang <yangjunlin@yulong.com>
+
+[ Upstream commit c38ae56ee034623c59e39c0130ca0dec086c1a39 ]
+
+The return from the call to platform_get_irq() is int, it can be
+a negative error code, however this is being assigned to an unsigned
+int variable 'irq', so making 'irq' an int, and change the position to
+keep the code format.
+
+./drivers/ata/pata_ixp4xx_cf.c:168:5-8:
+WARNING: Unsigned expression compared with zero: irq > 0
+
+Signed-off-by: Junlin Yang <yangjunlin@yulong.com>
+Link: https://lore.kernel.org/r/20210409135426.1773-1-angkery@163.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/pata_ixp4xx_cf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
+index abc0e87ca1a8..43215a4c1e54 100644
+--- a/drivers/ata/pata_ixp4xx_cf.c
++++ b/drivers/ata/pata_ixp4xx_cf.c
+@@ -135,12 +135,12 @@ static void ixp4xx_setup_port(struct ata_port *ap,
+ static int ixp4xx_pata_probe(struct platform_device *pdev)
+ {
+-      unsigned int irq;
+       struct resource *cs0, *cs1;
+       struct ata_host *host;
+       struct ata_port *ap;
+       struct ixp4xx_pata_data *data = dev_get_platdata(&pdev->dev);
+       int ret;
++      int irq;
+       cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+-- 
+2.35.1
+
diff --git a/queue-5.10/pci-check-for-alloc-failure-in-pci_request_irq.patch b/queue-5.10/pci-check-for-alloc-failure-in-pci_request_irq.patch
new file mode 100644 (file)
index 0000000..fcb7329
--- /dev/null
@@ -0,0 +1,39 @@
+From 711101cb78519f52a2471d2282f26fc0361e2049 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 10:00:29 +0800
+Subject: PCI: Check for alloc failure in pci_request_irq()
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit 2d9cd957d40c3ac491b358e7cff0515bb07a3a9c ]
+
+When kvasprintf() fails to allocate memory, it returns a NULL pointer.
+Return error from pci_request_irq() so we don't dereference it.
+
+[bhelgaas: commit log]
+Fixes: 704e8953d3e9 ("PCI/irq: Add pci_request_irq() and pci_free_irq() helpers")
+Link: https://lore.kernel.org/r/20221121020029.3759444-1-zengheng4@huawei.com
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/irq.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pci/irq.c b/drivers/pci/irq.c
+index 12ecd0aaa28d..0050e8f6814e 100644
+--- a/drivers/pci/irq.c
++++ b/drivers/pci/irq.c
+@@ -44,6 +44,8 @@ int pci_request_irq(struct pci_dev *dev, unsigned int nr, irq_handler_t handler,
+       va_start(ap, fmt);
+       devname = kvasprintf(GFP_KERNEL, fmt, ap);
+       va_end(ap);
++      if (!devname)
++              return -ENOMEM;
+       ret = request_threaded_irq(pci_irq_vector(dev, nr), handler, thread_fn,
+                                  irqflags, devname, dev_id);
+-- 
+2.35.1
+
diff --git a/queue-5.10/pci-dwc-fix-n_fts-array-overrun.patch b/queue-5.10/pci-dwc-fix-n_fts-array-overrun.patch
new file mode 100644 (file)
index 0000000..108ffeb
--- /dev/null
@@ -0,0 +1,42 @@
+From 784a734be14fb1641d0b5851655e23fed6a240bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Sep 2022 16:49:23 +0530
+Subject: PCI: dwc: Fix n_fts[] array overrun
+
+From: Vidya Sagar <vidyas@nvidia.com>
+
+[ Upstream commit 66110361281b2f7da0c8bd51eaf1f152f4236035 ]
+
+commit aeaa0bfe89654 ("PCI: dwc: Move N_FTS setup to common setup")
+incorrectly uses pci->link_gen in deriving the index to the
+n_fts[] array also introducing the issue of accessing beyond the
+boundaries of array for greater than Gen-2 speeds. This change fixes
+that issue.
+
+Link: https://lore.kernel.org/r/20220926111923.22487-1-vidyas@nvidia.com
+Fixes: aeaa0bfe8965 ("PCI: dwc: Move N_FTS setup to common setup")
+Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Acked-by: Jingoo Han <jingoohan1@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
+index 2b74ff88c5c5..28945351da14 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.c
++++ b/drivers/pci/controller/dwc/pcie-designware.c
+@@ -589,7 +589,7 @@ void dw_pcie_setup(struct dw_pcie *pci)
+       if (pci->n_fts[1]) {
+               val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
+               val &= ~PORT_LOGIC_N_FTS_MASK;
+-              val |= pci->n_fts[pci->link_gen - 1];
++              val |= pci->n_fts[1];
+               dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/pci-pci-epf-test-register-notifier-if-only-core_init.patch b/queue-5.10/pci-pci-epf-test-register-notifier-if-only-core_init.patch
new file mode 100644 (file)
index 0000000..0b2c3b1
--- /dev/null
@@ -0,0 +1,40 @@
+From ba134dc432bf9c2de4b59c356cfce435e8ba9778 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Aug 2022 18:01:01 +0900
+Subject: PCI: pci-epf-test: Register notifier if only core_init_notifier is
+ enabled
+
+From: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+
+[ Upstream commit 6acd25cc98ce0c9ee4fefdaf44fc8bca534b26e5 ]
+
+The pci_epf_test_notifier function should be installed also if only
+core_init_notifier is enabled. Fix the current logic.
+
+Link: https://lore.kernel.org/r/20220825090101.20474-1-hayashi.kunihiko@socionext.com
+Fixes: 5e50ee27d4a5 ("PCI: pci-epf-test: Add support to defer core initialization")
+Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Acked-by: Om Prakash Singh <omp@nvidia.com>
+Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index ddfeca9016a0..ef52f5097eb3 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -870,7 +870,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
+       if (ret)
+               epf_test->dma_supported = false;
+-      if (linkup_notifier) {
++      if (linkup_notifier || core_init_notifier) {
+               epf->nb.notifier_call = pci_epf_test_notifier;
+               pci_epc_register_notifier(epc, &epf->nb);
+       } else {
+-- 
+2.35.1
+
diff --git a/queue-5.10/perf-arm_dsu-fix-hotplug-callback-leak-in-dsu_pmu_in.patch b/queue-5.10/perf-arm_dsu-fix-hotplug-callback-leak-in-dsu_pmu_in.patch
new file mode 100644 (file)
index 0000000..94ceaf5
--- /dev/null
@@ -0,0 +1,46 @@
+From fbbf08515faba7908769f2f2208239ce1dc861c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 07:02:06 +0000
+Subject: perf: arm_dsu: Fix hotplug callback leak in dsu_pmu_init()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit facafab7611f7b872c6b9eeaff53461ef11f482e ]
+
+dsu_pmu_init() won't remove the callback added by cpuhp_setup_state_multi()
+when platform_driver_register() failed. Remove the callback by
+cpuhp_remove_multi_state() in fail path.
+
+Similar to the handling of arm_ccn_init() in commit 26242b330093 ("bus:
+arm-ccn: Prevent hotplug callback leak")
+
+Fixes: 7520fa99246d ("perf: ARM DynamIQ Shared Unit PMU support")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Acked-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20221115070207.32634-2-yuancan@huawei.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm_dsu_pmu.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
+index 98e68ed7db85..1db8eccc9735 100644
+--- a/drivers/perf/arm_dsu_pmu.c
++++ b/drivers/perf/arm_dsu_pmu.c
+@@ -866,7 +866,11 @@ static int __init dsu_pmu_init(void)
+       if (ret < 0)
+               return ret;
+       dsu_pmu_cpuhp_state = ret;
+-      return platform_driver_register(&dsu_pmu_driver);
++      ret = platform_driver_register(&dsu_pmu_driver);
++      if (ret)
++              cpuhp_remove_multi_state(dsu_pmu_cpuhp_state);
++
++      return ret;
+ }
+ static void __exit dsu_pmu_exit(void)
+-- 
+2.35.1
+
diff --git a/queue-5.10/perf-fix-possible-memleak-in-pmu_dev_alloc.patch b/queue-5.10/perf-fix-possible-memleak-in-pmu_dev_alloc.patch
new file mode 100644 (file)
index 0000000..0e1d449
--- /dev/null
@@ -0,0 +1,71 @@
+From 1a68b7b1faf8bbc7ea919774c047eb4ce66a2cf9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 18:36:53 +0800
+Subject: perf: Fix possible memleak in pmu_dev_alloc()
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit e8d7a90c08ce963c592fb49845f2ccc606a2ac21 ]
+
+In pmu_dev_alloc(), when dev_set_name() failed, it will goto free_dev
+and call put_device(pmu->dev) to release it.
+However pmu->dev->release is assigned after this, which makes warning
+and memleak.
+Call dev_set_name() after pmu->dev->release = pmu_dev_release to fix it.
+
+  Device '(null)' does not have a release() function...
+  WARNING: CPU: 2 PID: 441 at drivers/base/core.c:2332 device_release+0x1b9/0x240
+  ...
+  Call Trace:
+    <TASK>
+    kobject_put+0x17f/0x460
+    put_device+0x20/0x30
+    pmu_dev_alloc+0x152/0x400
+    perf_pmu_register+0x96b/0xee0
+    ...
+  kmemleak: 1 new suspected memory leaks (see /sys/kernel/debug/kmemleak)
+  unreferenced object 0xffff888014759000 (size 2048):
+    comm "modprobe", pid 441, jiffies 4294931444 (age 38.332s)
+    backtrace:
+      [<0000000005aed3b4>] kmalloc_trace+0x27/0x110
+      [<000000006b38f9b8>] pmu_dev_alloc+0x50/0x400
+      [<00000000735f17be>] perf_pmu_register+0x96b/0xee0
+      [<00000000e38477f1>] 0xffffffffc0ad8603
+      [<000000004e162216>] do_one_initcall+0xd0/0x4e0
+      ...
+
+Fixes: abe43400579d ("perf: Sysfs enumeration")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20221111103653.91058-1-chenzhongjin@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/core.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index e9b354d521a3..979d7946a772 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -10810,13 +10810,15 @@ static int pmu_dev_alloc(struct pmu *pmu)
+       pmu->dev->groups = pmu->attr_groups;
+       device_initialize(pmu->dev);
+-      ret = dev_set_name(pmu->dev, "%s", pmu->name);
+-      if (ret)
+-              goto free_dev;
+       dev_set_drvdata(pmu->dev, pmu);
+       pmu->dev->bus = &pmu_bus;
+       pmu->dev->release = pmu_dev_release;
++
++      ret = dev_set_name(pmu->dev, "%s", pmu->name);
++      if (ret)
++              goto free_dev;
++
+       ret = device_add(pmu->dev);
+       if (ret)
+               goto free_dev;
+-- 
+2.35.1
+
diff --git a/queue-5.10/perf-smmuv3-fix-hotplug-callback-leak-in-arm_smmu_pm.patch b/queue-5.10/perf-smmuv3-fix-hotplug-callback-leak-in-arm_smmu_pm.patch
new file mode 100644 (file)
index 0000000..98bbd82
--- /dev/null
@@ -0,0 +1,55 @@
+From 19ce3702dae675b25a3a445a5adb203b1030bd93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 19:55:40 +0800
+Subject: perf/smmuv3: Fix hotplug callback leak in arm_smmu_pmu_init()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit 6f2d566b46436a50a80d6445e82879686b89588c ]
+
+arm_smmu_pmu_init() won't remove the callback added by
+cpuhp_setup_state_multi() when platform_driver_register() failed. Remove
+the callback by cpuhp_remove_multi_state() in fail path.
+
+Similar to the handling of arm_ccn_init() in commit 26242b330093 ("bus:
+arm-ccn: Prevent hotplug callback leak")
+
+Fixes: 7d839b4b9e00 ("perf/smmuv3: Add arm64 smmuv3 pmu driver")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.com>
+Reviewed-by: Punit Agrawal <punit.agrawal@bytedance.com>
+Link: https://lore.kernel.org/r/20221115115540.6245-3-shangxiaojing@huawei.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm_smmuv3_pmu.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
+index afa8efbdad8f..f5a33dbe7acb 100644
+--- a/drivers/perf/arm_smmuv3_pmu.c
++++ b/drivers/perf/arm_smmuv3_pmu.c
+@@ -870,6 +870,8 @@ static struct platform_driver smmu_pmu_driver = {
+ static int __init arm_smmu_pmu_init(void)
+ {
++      int ret;
++
+       cpuhp_state_num = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
+                                                 "perf/arm/pmcg:online",
+                                                 NULL,
+@@ -877,7 +879,11 @@ static int __init arm_smmu_pmu_init(void)
+       if (cpuhp_state_num < 0)
+               return cpuhp_state_num;
+-      return platform_driver_register(&smmu_pmu_driver);
++      ret = platform_driver_register(&smmu_pmu_driver);
++      if (ret)
++              cpuhp_remove_multi_state(cpuhp_state_num);
++
++      return ret;
+ }
+ module_init(arm_smmu_pmu_init);
+-- 
+2.35.1
+
diff --git a/queue-5.10/perf-symbol-correction-while-adjusting-symbol.patch b/queue-5.10/perf-symbol-correction-while-adjusting-symbol.patch
new file mode 100644 (file)
index 0000000..dc7adb7
--- /dev/null
@@ -0,0 +1,76 @@
+From 9b8900f90dbeb1d32565f03539b1d96ff31c0ae3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 15:48:16 +0530
+Subject: perf symbol: correction while adjusting symbol
+
+From: Ajay Kaher <akaher@vmware.com>
+
+[ Upstream commit 6f520ce17920b3cdfbd2479b3ccf27f9706219d0 ]
+
+perf doesn't provide proper symbol information for specially crafted
+.debug files.
+
+Sometimes .debug file may not have similar program header as runtime
+ELF file. For example if we generate .debug file using objcopy
+--only-keep-debug resulting file will not contain .text, .data and
+other runtime sections. That means corresponding program headers will
+have zero FileSiz and modified Offset.
+
+Example: program header of text section of libxxx.so:
+
+Type           Offset             VirtAddr           PhysAddr
+               FileSiz            MemSiz              Flags  Align
+LOAD        0x00000000003d3000 0x00000000003d3000 0x00000000003d3000
+            0x000000000055ae80 0x000000000055ae80  R E    0x1000
+
+Same program header after executing:
+objcopy --only-keep-debug libxxx.so libxxx.so.debug
+
+LOAD        0x0000000000001000 0x00000000003d3000 0x00000000003d3000
+            0x0000000000000000 0x000000000055ae80  R E    0x1000
+
+Offset and FileSiz have been changed.
+
+Following formula will not provide correct value, if program header
+taken from .debug file (syms_ss):
+
+    sym.st_value -= phdr.p_vaddr - phdr.p_offset;
+
+Correct program header information is located inside runtime ELF
+file (runtime_ss).
+
+Fixes: 2d86612aacb7805f ("perf symbol: Correct address for bss symbols")
+Signed-off-by: Ajay Kaher <akaher@vmware.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Alexey Makhalov <amakhalov@vmware.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Srivatsa S. Bhat <srivatsab@vmware.com>
+Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Cc: Vasavi Sirnapalli <vsirnapalli@vmware.com>
+Link: http://lore.kernel.org/lkml/1669198696-50547-1-git-send-email-akaher@vmware.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/symbol-elf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
+index 3e423a920015..5221f272f85c 100644
+--- a/tools/perf/util/symbol-elf.c
++++ b/tools/perf/util/symbol-elf.c
+@@ -1247,7 +1247,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
+                          (!used_opd && syms_ss->adjust_symbols)) {
+                       GElf_Phdr phdr;
+-                      if (elf_read_program_header(syms_ss->elf,
++                      if (elf_read_program_header(runtime_ss->elf,
+                                                   (u64)sym.st_value, &phdr)) {
+                               pr_debug4("%s: failed to find program header for "
+                                          "symbol: %s st_value: %#" PRIx64 "\n",
+-- 
+2.35.1
+
diff --git a/queue-5.10/perf-trace-handle-failure-when-trace-point-folder-is.patch b/queue-5.10/perf-trace-handle-failure-when-trace-point-folder-is.patch
new file mode 100644 (file)
index 0000000..ea707b2
--- /dev/null
@@ -0,0 +1,93 @@
+From e0b2b74fbf0fc81900ed4cfaa6e976b469bfaf39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 07:52:35 +0000
+Subject: perf trace: Handle failure when trace point folder is missed
+
+From: Leo Yan <leo.yan@linaro.org>
+
+[ Upstream commit 03e9a5d8eb552a1bf692a9c8a5ecd50f4e428006 ]
+
+On Arm64 a case is perf tools fails to find the corresponding trace
+point folder for system calls listed in the table 'syscalltbl_arm64',
+e.g. the generated system call table contains "lookup_dcookie" but we
+cannot find out the matched trace point folder for it.
+
+We need to figure out if there have any issue for the generated system
+call table, on the other hand, we need to handle the case when trace
+point folder is missed under sysfs, this patch sets the flag
+syscall::nonexistent as true and returns the error from
+trace__read_syscall_info().
+
+Another problem is for trace__syscall_info(), it returns two different
+values if a system call doesn't exist: at the first time calling
+trace__syscall_info() it returns NULL when the system call doesn't exist,
+later if call trace__syscall_info() again for the same missed system
+call, it returns pointer of syscall.  trace__syscall_info() checks the
+condition 'syscalls.table[id].name == NULL', but the name will be
+assigned in the first invoking even the system call is not found.
+
+So checking system call's name in trace__syscall_info() is not the right
+thing to do, this patch simply checks flag syscall::nonexistent to make
+decision if a system call exists or not, finally trace__syscall_info()
+returns the consistent result (NULL) if a system call doesn't existed.
+
+Fixes: b8b1033fcaa091d8 ("perf trace: Mark syscall ids that are not allocated to avoid unnecessary error messages")
+Signed-off-by: Leo Yan <leo.yan@linaro.org>
+Acked-by: Ian Rogers <irogers@google.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: bpf@vger.kernel.org
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20221121075237.127706-4-leo.yan@linaro.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-trace.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index 1a7279687f25..8de0d0a740de 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -1794,13 +1794,19 @@ static int trace__read_syscall_info(struct trace *trace, int id)
+               sc->tp_format = trace_event__tp_format("syscalls", tp_name);
+       }
++      /*
++       * Fails to read trace point format via sysfs node, so the trace point
++       * doesn't exist.  Set the 'nonexistent' flag as true.
++       */
++      if (IS_ERR(sc->tp_format)) {
++              sc->nonexistent = true;
++              return PTR_ERR(sc->tp_format);
++      }
++
+       if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ?
+                                       RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields))
+               return -ENOMEM;
+-      if (IS_ERR(sc->tp_format))
+-              return PTR_ERR(sc->tp_format);
+-
+       sc->args = sc->tp_format->format.fields;
+       /*
+        * We need to check and discard the first variable '__syscall_nr'
+@@ -2117,11 +2123,8 @@ static struct syscall *trace__syscall_info(struct trace *trace,
+           (err = trace__read_syscall_info(trace, id)) != 0)
+               goto out_cant_read;
+-      if (trace->syscalls.table[id].name == NULL) {
+-              if (trace->syscalls.table[id].nonexistent)
+-                      return NULL;
++      if (trace->syscalls.table && trace->syscalls.table[id].nonexistent)
+               goto out_cant_read;
+-      }
+       return &trace->syscalls.table[id];
+-- 
+2.35.1
+
diff --git a/queue-5.10/perf-trace-return-error-if-a-system-call-doesn-t-exi.patch b/queue-5.10/perf-trace-return-error-if-a-system-call-doesn-t-exi.patch
new file mode 100644 (file)
index 0000000..6929298
--- /dev/null
@@ -0,0 +1,55 @@
+From 6dca143c4508299a9094ac0d173d07e529294c23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 07:52:34 +0000
+Subject: perf trace: Return error if a system call doesn't exist
+
+From: Leo Yan <leo.yan@linaro.org>
+
+[ Upstream commit d4223e1776c30b2ce8d0e6eaadcbf696e60fca3c ]
+
+When a system call is not detected, the reason is either because the
+system call ID is out of scope or failure to find the corresponding path
+in the sysfs, trace__read_syscall_info() returns zero.  Finally, without
+returning an error value it introduces confusion for the caller.
+
+This patch lets the function trace__read_syscall_info() to return
+-EEXIST when a system call doesn't exist.
+
+Fixes: b8b1033fcaa091d8 ("perf trace: Mark syscall ids that are not allocated to avoid unnecessary error messages")
+Signed-off-by: Leo Yan <leo.yan@linaro.org>
+Acked-by: Ian Rogers <irogers@google.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: bpf@vger.kernel.org
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20221121075237.127706-3-leo.yan@linaro.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-trace.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index de80534473af..555e16d8d55b 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -1774,11 +1774,11 @@ static int trace__read_syscall_info(struct trace *trace, int id)
+ #endif
+       sc = trace->syscalls.table + id;
+       if (sc->nonexistent)
+-              return 0;
++              return -EEXIST;
+       if (name == NULL) {
+               sc->nonexistent = true;
+-              return 0;
++              return -EEXIST;
+       }
+       sc->name = name;
+-- 
+2.35.1
+
diff --git a/queue-5.10/perf-trace-use-macro-raw_syscall_args_num-to-replace.patch b/queue-5.10/perf-trace-use-macro-raw_syscall_args_num-to-replace.patch
new file mode 100644 (file)
index 0000000..f588e84
--- /dev/null
@@ -0,0 +1,82 @@
+From a259541fbcb5ab464eb45ed987be3a128acc4c14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 07:52:33 +0000
+Subject: perf trace: Use macro RAW_SYSCALL_ARGS_NUM to replace number
+
+From: Leo Yan <leo.yan@linaro.org>
+
+[ Upstream commit eadcab4c7a66e1df03d32da0db55d89fd9343fcc ]
+
+This patch defines a macro RAW_SYSCALL_ARGS_NUM to replace the open
+coded number '6'.
+
+Signed-off-by: Leo Yan <leo.yan@linaro.org>
+Acked-by: Ian Rogers <irogers@google.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: bpf@vger.kernel.org
+Link: https://lore.kernel.org/r/20221121075237.127706-2-leo.yan@linaro.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 03e9a5d8eb55 ("perf trace: Handle failure when trace point folder is missed")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-trace.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index 555e16d8d55b..1a7279687f25 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -87,6 +87,8 @@
+ # define F_LINUX_SPECIFIC_BASE        1024
+ #endif
++#define RAW_SYSCALL_ARGS_NUM  6
++
+ /*
+  * strtoul: Go from a string to a value, i.e. for msr: MSR_FS_BASE to 0xc0000100
+  */
+@@ -107,7 +109,7 @@ struct syscall_fmt {
+               const char *sys_enter,
+                          *sys_exit;
+       }          bpf_prog_name;
+-      struct syscall_arg_fmt arg[6];
++      struct syscall_arg_fmt arg[RAW_SYSCALL_ARGS_NUM];
+       u8         nr_args;
+       bool       errpid;
+       bool       timeout;
+@@ -1216,7 +1218,7 @@ struct syscall {
+  */
+ struct bpf_map_syscall_entry {
+       bool    enabled;
+-      u16     string_args_len[6];
++      u16     string_args_len[RAW_SYSCALL_ARGS_NUM];
+ };
+ /*
+@@ -1641,7 +1643,7 @@ static int syscall__alloc_arg_fmts(struct syscall *sc, int nr_args)
+ {
+       int idx;
+-      if (nr_args == 6 && sc->fmt && sc->fmt->nr_args != 0)
++      if (nr_args == RAW_SYSCALL_ARGS_NUM && sc->fmt && sc->fmt->nr_args != 0)
+               nr_args = sc->fmt->nr_args;
+       sc->arg_fmt = calloc(nr_args, sizeof(*sc->arg_fmt));
+@@ -1792,7 +1794,8 @@ static int trace__read_syscall_info(struct trace *trace, int id)
+               sc->tp_format = trace_event__tp_format("syscalls", tp_name);
+       }
+-      if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? 6 : sc->tp_format->format.nr_fields))
++      if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ?
++                                      RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields))
+               return -ENOMEM;
+       if (IS_ERR(sc->tp_format))
+-- 
+2.35.1
+
diff --git a/queue-5.10/perf-x86-intel-uncore-fix-reference-count-leak-in-__.patch b/queue-5.10/perf-x86-intel-uncore-fix-reference-count-leak-in-__.patch
new file mode 100644 (file)
index 0000000..3d17f78
--- /dev/null
@@ -0,0 +1,50 @@
+From 0591dae652b950e4d1f4a77ba462c8e551181e5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 14:31:37 +0800
+Subject: perf/x86/intel/uncore: Fix reference count leak in
+ __uncore_imc_init_box()
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit 17b8d847b92d815d1638f0de154654081d66b281 ]
+
+pci_get_device() will increase the reference count for the returned
+pci_dev, so tgl_uncore_get_mc_dev() will return a pci_dev with its
+reference count increased. We need to call pci_dev_put() to decrease the
+reference count before exiting from __uncore_imc_init_box(). Add
+pci_dev_put() for both normal and error path.
+
+Fixes: fdb64822443e ("perf/x86: Add Intel Tiger Lake uncore support")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Link: https://lore.kernel.org/r/20221118063137.121512-5-wangxiongfeng2@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/intel/uncore_snb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
+index fa9289718147..a4c20e37bec2 100644
+--- a/arch/x86/events/intel/uncore_snb.c
++++ b/arch/x86/events/intel/uncore_snb.c
+@@ -1274,6 +1274,7 @@ static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
+       /* MCHBAR is disabled */
+       if (!(mch_bar & BIT(0))) {
+               pr_warn("perf uncore: MCHBAR is disabled. Failed to map IMC free-running counters.\n");
++              pci_dev_put(pdev);
+               return;
+       }
+       mch_bar &= ~BIT(0);
+@@ -1287,6 +1288,8 @@ static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
+       box->io_addr = ioremap(addr, type->mmio_map_size);
+       if (!box->io_addr)
+               pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
++
++      pci_dev_put(pdev);
+ }
+ static struct intel_uncore_ops tgl_uncore_imc_freerunning_ops = {
+-- 
+2.35.1
+
diff --git a/queue-5.10/perf-x86-intel-uncore-fix-reference-count-leak-in-hs.patch b/queue-5.10/perf-x86-intel-uncore-fix-reference-count-leak-in-hs.patch
new file mode 100644 (file)
index 0000000..dfb0e9d
--- /dev/null
@@ -0,0 +1,40 @@
+From 91cca2d77db3c71c20b9264c6cf4a975b8134ca9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 14:31:35 +0800
+Subject: perf/x86/intel/uncore: Fix reference count leak in
+ hswep_has_limit_sbox()
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit 1ff9dd6e7071a561f803135c1d684b13c7a7d01d ]
+
+pci_get_device() will increase the reference count for the returned
+'dev'. We need to call pci_dev_put() to decrease the reference count.
+Since 'dev' is only used in pci_read_config_dword(), let's add
+pci_dev_put() right after it.
+
+Fixes: 9d480158ee86 ("perf/x86/intel/uncore: Remove uncore extra PCI dev HSWEP_PCI_PCU_3")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Link: https://lore.kernel.org/r/20221118063137.121512-3-wangxiongfeng2@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/intel/uncore_snbep.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
+index 03c8047bebb3..aa5da42ff948 100644
+--- a/arch/x86/events/intel/uncore_snbep.c
++++ b/arch/x86/events/intel/uncore_snbep.c
+@@ -2828,6 +2828,7 @@ static bool hswep_has_limit_sbox(unsigned int device)
+               return false;
+       pci_read_config_dword(dev, HSWEP_PCU_CAPID4_OFFET, &capid4);
++      pci_dev_put(dev);
+       if (!hswep_get_chop(capid4))
+               return true;
+-- 
+2.35.1
+
diff --git a/queue-5.10/perf-x86-intel-uncore-fix-reference-count-leak-in-sn.patch b/queue-5.10/perf-x86-intel-uncore-fix-reference-count-leak-in-sn.patch
new file mode 100644 (file)
index 0000000..86ac40b
--- /dev/null
@@ -0,0 +1,41 @@
+From 96c7251bb5d4fab4ae21a7b9d5b99c2878026bab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 14:31:36 +0800
+Subject: perf/x86/intel/uncore: Fix reference count leak in
+ snr_uncore_mmio_map()
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit 8ebd16c11c346751b3944d708e6c181ed4746c39 ]
+
+pci_get_device() will increase the reference count for the returned
+pci_dev, so snr_uncore_get_mc_dev() will return a pci_dev with its
+reference count increased. We need to call pci_dev_put() to decrease the
+reference count. Let's add the missing pci_dev_put().
+
+Fixes: ee49532b38dd ("perf/x86/intel/uncore: Add IMC uncore support for Snow Ridge")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Link: https://lore.kernel.org/r/20221118063137.121512-4-wangxiongfeng2@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/intel/uncore_snbep.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
+index aa5da42ff948..2fd49cd515f5 100644
+--- a/arch/x86/events/intel/uncore_snbep.c
++++ b/arch/x86/events/intel/uncore_snbep.c
+@@ -4681,6 +4681,8 @@ static void __snr_uncore_mmio_init_box(struct intel_uncore_box *box,
+       addr += box_ctl;
++      pci_dev_put(pdev);
++
+       box->io_addr = ioremap(addr, type->mmio_map_size);
+       if (!box->io_addr) {
+               pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
+-- 
+2.35.1
+
diff --git a/queue-5.10/phy-qcom-qmp-combo-fix-runtime-suspend.patch b/queue-5.10/phy-qcom-qmp-combo-fix-runtime-suspend.patch
new file mode 100644 (file)
index 0000000..34c62ab
--- /dev/null
@@ -0,0 +1,69 @@
+From 5611e9f50349b50caffc774a88a6b48a118cf9c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 09:13:45 +0100
+Subject: phy: qcom-qmp-combo: fix runtime suspend
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit c7b98de745cffdceefc077ad5cf9cda032ef8959 ]
+
+Drop the confused runtime-suspend type check which effectively broke
+runtime PM if the DP child node happens to be parsed before the USB
+child node during probe (e.g. due to order of child nodes in the
+devicetree).
+
+Instead use the new driver data USB PHY pointer to access the USB
+configuration and resources.
+
+Fixes: 52e013d0bffa ("phy: qcom-qmp: Add support for DP in USB3+DP combo phy")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20221114081346.5116-6-johan+linaro@kernel.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 12 ++----------
+ 1 file changed, 2 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+index c7309e981bfb..013fe758f5ad 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+@@ -5501,15 +5501,11 @@ static void qcom_qmp_phy_disable_autonomous_mode(struct qmp_phy *qphy)
+ static int __maybe_unused qcom_qmp_phy_runtime_suspend(struct device *dev)
+ {
+       struct qcom_qmp *qmp = dev_get_drvdata(dev);
+-      struct qmp_phy *qphy = qmp->phys[0];
++      struct qmp_phy *qphy = qmp->usb_phy;
+       const struct qmp_phy_cfg *cfg = qphy->cfg;
+       dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qphy->mode);
+-      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
+-      if (cfg->type != PHY_TYPE_USB3)
+-              return 0;
+-
+       if (!qmp->init_count) {
+               dev_vdbg(dev, "PHY not initialized, bailing out\n");
+               return 0;
+@@ -5526,16 +5522,12 @@ static int __maybe_unused qcom_qmp_phy_runtime_suspend(struct device *dev)
+ static int __maybe_unused qcom_qmp_phy_runtime_resume(struct device *dev)
+ {
+       struct qcom_qmp *qmp = dev_get_drvdata(dev);
+-      struct qmp_phy *qphy = qmp->phys[0];
++      struct qmp_phy *qphy = qmp->usb_phy;
+       const struct qmp_phy_cfg *cfg = qphy->cfg;
+       int ret = 0;
+       dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qphy->mode);
+-      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
+-      if (cfg->type != PHY_TYPE_USB3)
+-              return 0;
+-
+       if (!qmp->init_count) {
+               dev_vdbg(dev, "PHY not initialized, bailing out\n");
+               return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/phy-qcom-qmp-create-copies-of-qmp-phy-driver.patch b/queue-5.10/phy-qcom-qmp-create-copies-of-qmp-phy-driver.patch
new file mode 100644 (file)
index 0000000..b897f54
--- /dev/null
@@ -0,0 +1,31819 @@
+From 49bed6344194210877fd3882d16ce7be48b2063d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 00:35:32 +0300
+Subject: phy: qcom-qmp: create copies of QMP PHY driver
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 94a407cc17a445ddb3f7315cee0b0916d35d177c ]
+
+In order to split and cleanup the single monstrous QMP PHY driver,
+create blind copies of the current file. They will be used for:
+- PCIe (and a separate msm8996 PCIe PHY driver)
+- UFS
+- USB
+- Combo DP + USB
+
+Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Tested-by: Bjorn Andersson <bjorn.andersson@linaro.org> # UFS, PCIe and USB on SC8180X
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20220607213203.2819885-2-dmitry.baryshkov@linaro.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: c7b98de745cf ("phy: qcom-qmp-combo: fix runtime suspend")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/qualcomm/phy-qcom-qmp-combo.c     | 6350 +++++++++++++++++
+ .../phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c  | 6350 +++++++++++++++++
+ drivers/phy/qualcomm/phy-qcom-qmp-pcie.c      | 6350 +++++++++++++++++
+ drivers/phy/qualcomm/phy-qcom-qmp-ufs.c       | 6350 +++++++++++++++++
+ drivers/phy/qualcomm/phy-qcom-qmp-usb.c       | 6350 +++++++++++++++++
+ 5 files changed, 31750 insertions(+)
+ create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+ create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
+ create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+ create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+ create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+new file mode 100644
+index 000000000000..c7309e981bfb
+--- /dev/null
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+@@ -0,0 +1,6350 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++
++#include <dt-bindings/phy/phy.h>
++
++#include "phy-qcom-qmp.h"
++
++/* QPHY_SW_RESET bit */
++#define SW_RESET                              BIT(0)
++/* QPHY_POWER_DOWN_CONTROL */
++#define SW_PWRDN                              BIT(0)
++#define REFCLK_DRV_DSBL                               BIT(1)
++/* QPHY_START_CONTROL bits */
++#define SERDES_START                          BIT(0)
++#define PCS_START                             BIT(1)
++#define PLL_READY_GATE_EN                     BIT(3)
++/* QPHY_PCS_STATUS bit */
++#define PHYSTATUS                             BIT(6)
++#define PHYSTATUS_4_20                                BIT(7)
++/* QPHY_PCS_READY_STATUS & QPHY_COM_PCS_READY_STATUS bit */
++#define PCS_READY                             BIT(0)
++
++/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
++/* DP PHY soft reset */
++#define SW_DPPHY_RESET                                BIT(0)
++/* mux to select DP PHY reset control, 0:HW control, 1: software reset */
++#define SW_DPPHY_RESET_MUX                    BIT(1)
++/* USB3 PHY soft reset */
++#define SW_USB3PHY_RESET                      BIT(2)
++/* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
++#define SW_USB3PHY_RESET_MUX                  BIT(3)
++
++/* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
++#define USB3_MODE                             BIT(0) /* enables USB3 mode */
++#define DP_MODE                                       BIT(1) /* enables DP mode */
++
++/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
++#define ARCVR_DTCT_EN                         BIT(0)
++#define ALFPS_DTCT_EN                         BIT(1)
++#define ARCVR_DTCT_EVENT_SEL                  BIT(4)
++
++/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
++#define IRQ_CLEAR                             BIT(0)
++
++/* QPHY_PCS_LFPS_RXTERM_IRQ_STATUS register bits */
++#define RCVR_DETECT                           BIT(0)
++
++/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
++#define CLAMP_EN                              BIT(0) /* enables i/o clamp_n */
++
++#define PHY_INIT_COMPLETE_TIMEOUT             10000
++#define POWER_DOWN_DELAY_US_MIN                       10
++#define POWER_DOWN_DELAY_US_MAX                       11
++
++#define MAX_PROP_NAME                         32
++
++/* Define the assumed distance between lanes for underspecified device trees. */
++#define QMP_PHY_LEGACY_LANE_STRIDE            0x400
++
++struct qmp_phy_init_tbl {
++      unsigned int offset;
++      unsigned int val;
++      /*
++       * register part of layout ?
++       * if yes, then offset gives index in the reg-layout
++       */
++      bool in_layout;
++      /*
++       * mask of lanes for which this register is written
++       * for cases when second lane needs different values
++       */
++      u8 lane_mask;
++};
++
++#define QMP_PHY_INIT_CFG(o, v)                \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .lane_mask = 0xff,      \
++      }
++
++#define QMP_PHY_INIT_CFG_L(o, v)      \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .in_layout = true,      \
++              .lane_mask = 0xff,      \
++      }
++
++#define QMP_PHY_INIT_CFG_LANE(o, v, l)        \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .lane_mask = l,         \
++      }
++
++/* set of registers with offsets different per-PHY */
++enum qphy_reg_layout {
++      /* Common block control registers */
++      QPHY_COM_SW_RESET,
++      QPHY_COM_POWER_DOWN_CONTROL,
++      QPHY_COM_START_CONTROL,
++      QPHY_COM_PCS_READY_STATUS,
++      /* PCS registers */
++      QPHY_PLL_LOCK_CHK_DLY_TIME,
++      QPHY_FLL_CNTRL1,
++      QPHY_FLL_CNTRL2,
++      QPHY_FLL_CNT_VAL_L,
++      QPHY_FLL_CNT_VAL_H_TOL,
++      QPHY_FLL_MAN_CODE,
++      QPHY_SW_RESET,
++      QPHY_START_CTRL,
++      QPHY_PCS_READY_STATUS,
++      QPHY_PCS_STATUS,
++      QPHY_PCS_AUTONOMOUS_MODE_CTRL,
++      QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
++      QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
++      QPHY_PCS_POWER_DOWN_CONTROL,
++      /* PCS_MISC registers */
++      QPHY_PCS_MISC_TYPEC_CTRL,
++      /* Keep last to ensure regs_layout arrays are properly initialized */
++      QPHY_LAYOUT_SIZE
++};
++
++static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x168,
++};
++
++static const unsigned int ipq_pciephy_gen3_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                         = 0x00,
++      [QPHY_START_CTRL]                       = 0x44,
++      [QPHY_PCS_STATUS]                       = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]           = 0x40,
++};
++
++static const unsigned int pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_COM_SW_RESET]             = 0x400,
++      [QPHY_COM_POWER_DOWN_CONTROL]   = 0x404,
++      [QPHY_COM_START_CONTROL]        = 0x408,
++      [QPHY_COM_PCS_READY_STATUS]     = 0x448,
++      [QPHY_PLL_LOCK_CHK_DLY_TIME]    = 0xa8,
++      [QPHY_FLL_CNTRL1]               = 0xc4,
++      [QPHY_FLL_CNTRL2]               = 0xc8,
++      [QPHY_FLL_CNT_VAL_L]            = 0xcc,
++      [QPHY_FLL_CNT_VAL_H_TOL]        = 0xd0,
++      [QPHY_FLL_MAN_CODE]             = 0xd4,
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++};
++
++static const unsigned int usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_FLL_CNTRL1]               = 0xc0,
++      [QPHY_FLL_CNTRL2]               = 0xc4,
++      [QPHY_FLL_CNT_VAL_L]            = 0xc8,
++      [QPHY_FLL_CNT_VAL_H_TOL]        = 0xcc,
++      [QPHY_FLL_MAN_CODE]             = 0xd0,
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x17c,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d4,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0d8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178,
++};
++
++static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0dc,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
++};
++
++static const unsigned int sdm845_qmp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++};
++
++static const unsigned int sdm845_qhp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x2ac,
++};
++
++static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x308,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x314,
++};
++
++static const unsigned int qmp_v4_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x608,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x614,
++};
++
++static const unsigned int sm8350_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x1008,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x1014,
++};
++
++static const unsigned int qcm2290_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x04,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0xd8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0xdc,
++      [QPHY_PCS_STATUS]               = 0x174,
++      [QPHY_PCS_MISC_TYPEC_CTRL]      = 0x00,
++};
++
++static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x160,
++};
++
++static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x168,
++};
++
++static const unsigned int sm8250_pcie_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++};
++
++static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = QPHY_V4_PCS_UFS_PHY_START,
++      [QPHY_PCS_READY_STATUS]         = QPHY_V4_PCS_UFS_READY_STATUS,
++      [QPHY_SW_RESET]                 = QPHY_V4_PCS_UFS_SW_RESET,
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      /* PLL and Loop filter settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      /* SSC settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x0),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x40),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x19),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_RX_IDLE_DTCT_CNTRL, 0x4c),
++      QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++
++      QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x05),
++
++      QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x05),
++      QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG4, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG1, 0xa3),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0x0e),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x7e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x15),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x40),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x99),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x04),
++      /* PLL and Loop filter settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      /* SSC settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xbb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL2, 0x03),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_H_TOL, 0x42),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_MAN_CODE, 0x85),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG2, 0x08),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x29),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x53),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_TX0_LANE_MODE_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_TX0_RCV_DETECT_LVL_2, 0x12),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_GAIN, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0x61),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_LOW, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH2, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH3, 0xd3),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH4, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_LOW, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_DFE_EN_TIMER, 0x04),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL1, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(PCS_COM_G12S1_TXDEEMPH_M3P5DB, 0x10),
++      QMP_PHY_INIT_CFG(PCS_COM_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_RX_DCC_CAL_CONFIG, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_EQ_CONFIG5, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
++      QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
++      QMP_PHY_INIT_CFG(PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++      QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG1, 0x11),
++      QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_POST, 0x58),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0xf),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0xf),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x3),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0xD),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xD04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0xb),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x6),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_TX_EMP_POST1_LVL, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_TX_SLEW_CNTL, 0x0a),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x4),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x4),
++      QMP_PHY_INIT_CFG(QPHY_OSC_DTCT_ACTIONS, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x40),
++      QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x73),
++      QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_LVL, 0x99),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0xe),
++      QMP_PHY_INIT_CFG_L(QPHY_SW_RESET, 0x0),
++      QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x007),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x7e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x15),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_01, 0x59),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x40),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE, 0x04),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xbb),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG4, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_CONFIG2, 0x52),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG2, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG4, 0x1a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG5, 0x06),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SYSCLK_EN_SEL, 0x27),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE2, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BIAS_EN_CKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CLK_ENABLE1, 0xb0),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP1_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP2_MODE0, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_RESTRIM_CTRL2, 0x05),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VCO_TUNE_MAP, 0x10),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CLK_SELECT, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_HSCLK_SEL1, 0x30),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORECLK_DIV, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORE_CLK_EN, 0x73),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CMN_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SVS_MODE_CLK_SEL, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VREGCLK_DIV1, 0x22),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VREGCLK_DIV2, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BGV_TRIM, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BG_CTRL, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL0, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_TAP_EN, 0x0d),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_TX_BAND_MODE, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_LANE_MODE, 0x1a),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PARALLEL_RATE, 0x2f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE0, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE1, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE2, 0x1b),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PREAMP_CTRL_MODE1, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PREAMP_CTRL_MODE2, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE0, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE1, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE2, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_THRESH_DFE, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CGA_THRESH_DFE, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXENGINE_EN0, 0x12),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_TRAIN_TIME, 0x25),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_DFE_OVRLP_TIME, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_REFRESH_TIME, 0x05),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_ENABLE_TIME, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_VGA_GAIN, 0x26),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_GAIN, 0x12),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EQ_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_OFFSET_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PRE_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EQ_INTVAL, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EDAC_INITVAL, 0x28),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_INITB0, 0x7f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_INITB1, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RCVRDONE_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_CTRL, 0x70),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE0, 0x8b),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE2, 0x0a),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE2, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_BAND, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE0, 0x5c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE1, 0x3e),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE2, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_ENABLES, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_CNTRL, 0xa0),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_DEGLITCH_CNTRL, 0x08),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DCC_GAIN, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_EN_SIGNAL, 0xc3),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PSM_RX_EN_CAL, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_MISC_CNTRL0, 0xbc),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_TS0_TIMER, 0x7f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DLL_HIGHDATARATE, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RESETCODE_OFFSET, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_VGA_INITVAL, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RSM_START, 0x01),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_rx_tbl[] = {
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_PCS_TX_RX_CONFIG, 0x50),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_MAIN_V0_M3P5DB, 0x19),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_POST_V0_M3P5DB, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_MAIN_V0_M6DB, 0x17),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_POST_V0_M6DB, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG5, 0x9f),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_rbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x6f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr2[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr3[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRANSCEIVER_BIAS_EN, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_VMODE_CTRL1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_INTERFACE_SELECT, 0x3d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_CLKBUF_ENABLE, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RESET_TSYNC_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRAN_DRVR_EMP_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_BAND, 0x4),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_POL_INV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_DRV_LVL, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_EMP_POST1_LVL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb5),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4c),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x64),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_RX_PWM_GEAR_BAND, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_DRV_LVL, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
++      QMP_PHY_INIT_CFG(QPHY_RX_SYM_RESYNC_CTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
++      QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_CTRL2, 0x6e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SYM_RESYNC_CTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_CTRL1, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_MIN_HIBERN8_TIME, 0x9a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_INITVAL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x43),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x8a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
++
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x94),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_pcs_tbl[] = {
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x95),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xef),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x60),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x60),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x40, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x54, 2),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0xff, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f, 2),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff, 2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x97),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORE_CLK_EN, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_rbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x6f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr2[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr3[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_VMODE_CTRL1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_INTERFACE_SELECT, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_CLKBUF_ENABLE, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RESET_TSYNC_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_BAND, 0x4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_POL_INV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_DRV_LVL, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_EMP_POST1_LVL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x5),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x6e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x6e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x39),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x39),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x01),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x35),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x30),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x12),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE, 0x33),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x05),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG2, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x08),
++};
++
++static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x26),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x048),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x46),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_CFG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x50),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MISC1, 0x88),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTERNAL_DIG_CORECLK_DIV, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MODE, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_DC_LEVEL_CTRL, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x56),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x22),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_3, 0x13),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_VMODE_CTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_PI_QEC_CTRL, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_FO_GAIN_RATE2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_UCDR_PI_CONTROLS, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_AUX_DATA_TCOARSE_TFINE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_3, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_VGA_CAL_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B1, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B2, 0x5a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B4, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B0, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B1, 0xf9),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B3, 0xce),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B4, 0x62),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B0, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B1, 0x7d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B3, 0xcf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B4, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_PHPRE_CTRL, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_MARG_COARSE_CTRL2, 0x12),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG2, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG4, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG5, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_EQ_CONFIG1, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G3_RXEQEVAL_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_RXEQEVAL_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG2, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_SW_CTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_MX_CTRL2, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdx65_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0b),
++};
++
++static const struct qmp_phy_init_tbl sdx65_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_ENABLES, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_PLL_CNTL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_RX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x35),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_5, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xbb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbb),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3d, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3c, 2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xd2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x13),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_ENABLES, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_INITVAL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x01),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x04),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xd8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_TX_ADAPT_POST_THRESH, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RATE_SLEW_CNTRL1, 0x0b),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG2, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x97),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x46),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_CFG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0xd0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MISC1, 0x88),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORE_CLK_EN, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MODE, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_DC_LEVEL_CTRL, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_PI_CONTROLS, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B1, 0xcc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B3, 0xcc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B5, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B6, 0x29),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B0, 0xc5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B1, 0xad),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B2, 0xb6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B3, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B4, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B5, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B6, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B0, 0xc7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B1, 0xef),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B3, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B4, 0x81),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B5, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B6, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_PHPRE_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_0_1, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_2_3, 0x37),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_3, 0x05),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE3, 0x1f),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE210, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE210, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE210, 0x1f),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE3, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_VGA_CAL_MAN_VAL, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_IDAC_SAOFFSET, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_DAC_ENABLE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_GM_CAL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH2, 0x1f),
++};
++
++/* Register names should be validated, they might be different for this PHY */
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG2, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG3, 0x22),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_G3S2_PRE_GAIN, 0x2e),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x99),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_EQ_CONFIG1, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_RX_MARGINING_CONFIG3, 0x28),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_PRE_GAIN, 0x2e),
++};
++
++struct qmp_phy;
++
++/* struct qmp_phy_cfg - per-PHY initialization config */
++struct qmp_phy_cfg {
++      /* phy-type - PCIE/UFS/USB */
++      unsigned int type;
++      /* number of lanes provided by phy */
++      int nlanes;
++
++      /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
++      const struct qmp_phy_init_tbl *serdes_tbl;
++      int serdes_tbl_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_sec;
++      int serdes_tbl_num_sec;
++      const struct qmp_phy_init_tbl *tx_tbl;
++      int tx_tbl_num;
++      const struct qmp_phy_init_tbl *tx_tbl_sec;
++      int tx_tbl_num_sec;
++      const struct qmp_phy_init_tbl *rx_tbl;
++      int rx_tbl_num;
++      const struct qmp_phy_init_tbl *rx_tbl_sec;
++      int rx_tbl_num_sec;
++      const struct qmp_phy_init_tbl *pcs_tbl;
++      int pcs_tbl_num;
++      const struct qmp_phy_init_tbl *pcs_tbl_sec;
++      int pcs_tbl_num_sec;
++      const struct qmp_phy_init_tbl *pcs_misc_tbl;
++      int pcs_misc_tbl_num;
++      const struct qmp_phy_init_tbl *pcs_misc_tbl_sec;
++      int pcs_misc_tbl_num_sec;
++
++      /* Init sequence for DP PHY block link rates */
++      const struct qmp_phy_init_tbl *serdes_tbl_rbr;
++      int serdes_tbl_rbr_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr;
++      int serdes_tbl_hbr_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr2;
++      int serdes_tbl_hbr2_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr3;
++      int serdes_tbl_hbr3_num;
++
++      /* DP PHY callbacks */
++      int (*configure_dp_phy)(struct qmp_phy *qphy);
++      void (*configure_dp_tx)(struct qmp_phy *qphy);
++      int (*calibrate_dp_phy)(struct qmp_phy *qphy);
++      void (*dp_aux_init)(struct qmp_phy *qphy);
++
++      /* clock ids to be requested */
++      const char * const *clk_list;
++      int num_clks;
++      /* resets to be requested */
++      const char * const *reset_list;
++      int num_resets;
++      /* regulators to be requested */
++      const char * const *vreg_list;
++      int num_vregs;
++
++      /* array of registers with different offsets */
++      const unsigned int *regs;
++
++      unsigned int start_ctrl;
++      unsigned int pwrdn_ctrl;
++      unsigned int mask_com_pcs_ready;
++      /* bit offset of PHYSTATUS in QPHY_PCS_STATUS register */
++      unsigned int phy_status;
++
++      /* true, if PHY has a separate PHY_COM control block */
++      bool has_phy_com_ctrl;
++      /* true, if PHY has a reset for individual lanes */
++      bool has_lane_rst;
++      /* true, if PHY needs delay after POWER_DOWN */
++      bool has_pwrdn_delay;
++      /* power_down delay in usec */
++      int pwrdn_delay_min;
++      int pwrdn_delay_max;
++
++      /* true, if PHY has a separate DP_COM control block */
++      bool has_phy_dp_com_ctrl;
++      /* true, if PHY has secondary tx/rx lanes to be configured */
++      bool is_dual_lane_phy;
++
++      /* true, if PCS block has no separate SW_RESET register */
++      bool no_pcs_sw_reset;
++};
++
++struct qmp_phy_combo_cfg {
++      const struct qmp_phy_cfg *usb_cfg;
++      const struct qmp_phy_cfg *dp_cfg;
++};
++
++/**
++ * struct qmp_phy - per-lane phy descriptor
++ *
++ * @phy: generic phy
++ * @cfg: phy specific configuration
++ * @serdes: iomapped memory space for phy's serdes (i.e. PLL)
++ * @tx: iomapped memory space for lane's tx
++ * @rx: iomapped memory space for lane's rx
++ * @pcs: iomapped memory space for lane's pcs
++ * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
++ * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
++ * @pcs_misc: iomapped memory space for lane's pcs_misc
++ * @pipe_clk: pipe clock
++ * @index: lane index
++ * @qmp: QMP phy to which this lane belongs
++ * @lane_rst: lane's reset controller
++ * @mode: current PHY mode
++ * @dp_aux_cfg: Display port aux config
++ * @dp_opts: Display port optional config
++ * @dp_clks: Display port clocks
++ */
++struct qmp_phy {
++      struct phy *phy;
++      const struct qmp_phy_cfg *cfg;
++      void __iomem *serdes;
++      void __iomem *tx;
++      void __iomem *rx;
++      void __iomem *pcs;
++      void __iomem *tx2;
++      void __iomem *rx2;
++      void __iomem *pcs_misc;
++      struct clk *pipe_clk;
++      unsigned int index;
++      struct qcom_qmp *qmp;
++      struct reset_control *lane_rst;
++      enum phy_mode mode;
++      unsigned int dp_aux_cfg;
++      struct phy_configure_opts_dp dp_opts;
++      struct qmp_phy_dp_clks *dp_clks;
++};
++
++struct qmp_phy_dp_clks {
++      struct qmp_phy *qphy;
++      struct clk_hw dp_link_hw;
++      struct clk_hw dp_pixel_hw;
++};
++
++/**
++ * struct qcom_qmp - structure holding QMP phy block attributes
++ *
++ * @dev: device
++ * @dp_com: iomapped memory space for phy's dp_com control block
++ *
++ * @clks: array of clocks required by phy
++ * @resets: array of resets required by phy
++ * @vregs: regulator supplies bulk data
++ *
++ * @phys: array of per-lane phy descriptors
++ * @phy_mutex: mutex lock for PHY common block initialization
++ * @init_count: phy common block initialization count
++ * @ufs_reset: optional UFS PHY reset handle
++ */
++struct qcom_qmp {
++      struct device *dev;
++      void __iomem *dp_com;
++
++      struct clk_bulk_data *clks;
++      struct reset_control **resets;
++      struct regulator_bulk_data *vregs;
++
++      struct qmp_phy **phys;
++
++      struct mutex phy_mutex;
++      int init_count;
++
++      struct reset_control *ufs_reset;
++};
++
++static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy);
++static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy);
++static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy);
++static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy);
++
++static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy);
++static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy);
++static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy);
++static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy);
++
++static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
++{
++      u32 reg;
++
++      reg = readl(base + offset);
++      reg |= val;
++      writel(reg, base + offset);
++
++      /* ensure that above write is through */
++      readl(base + offset);
++}
++
++static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
++{
++      u32 reg;
++
++      reg = readl(base + offset);
++      reg &= ~val;
++      writel(reg, base + offset);
++
++      /* ensure that above write is through */
++      readl(base + offset);
++}
++
++/* list of clocks required by phy */
++static const char * const msm8996_phy_clk_l[] = {
++      "aux", "cfg_ahb", "ref",
++};
++
++static const char * const msm8996_ufs_phy_clk_l[] = {
++      "ref",
++};
++
++static const char * const qmp_v3_phy_clk_l[] = {
++      "aux", "cfg_ahb", "ref", "com_aux",
++};
++
++static const char * const sdm845_pciephy_clk_l[] = {
++      "aux", "cfg_ahb", "ref", "refgen",
++};
++
++static const char * const qmp_v4_phy_clk_l[] = {
++      "aux", "ref_clk_src", "ref", "com_aux",
++};
++
++/* the primary usb3 phy on sm8250 doesn't have a ref clock */
++static const char * const qmp_v4_sm8250_usbphy_clk_l[] = {
++      "aux", "ref_clk_src", "com_aux"
++};
++
++static const char * const sm8450_ufs_phy_clk_l[] = {
++      "qref", "ref", "ref_aux",
++};
++
++static const char * const sdm845_ufs_phy_clk_l[] = {
++      "ref", "ref_aux",
++};
++
++/* usb3 phy on sdx55 doesn't have com_aux clock */
++static const char * const qmp_v4_sdx55_usbphy_clk_l[] = {
++      "aux", "cfg_ahb", "ref"
++};
++
++static const char * const qcm2290_usb3phy_clk_l[] = {
++      "cfg_ahb", "ref", "com_aux",
++};
++
++/* list of resets */
++static const char * const msm8996_pciephy_reset_l[] = {
++      "phy", "common", "cfg",
++};
++
++static const char * const msm8996_usb3phy_reset_l[] = {
++      "phy", "common",
++};
++
++static const char * const sc7180_usb3phy_reset_l[] = {
++      "phy",
++};
++
++static const char * const qcm2290_usb3phy_reset_l[] = {
++      "phy_phy", "phy",
++};
++
++static const char * const sdm845_pciephy_reset_l[] = {
++      "phy",
++};
++
++/* list of regulators */
++static const char * const qmp_phy_vreg_l[] = {
++      "vdda-phy", "vdda-pll",
++};
++
++static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq8074_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq8074_usb3_serdes_tbl),
++      .tx_tbl                 = msm8996_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_usb3_tx_tbl),
++      .rx_tbl                 = ipq8074_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq8074_usb3_rx_tbl),
++      .pcs_tbl                = ipq8074_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq8074_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++};
++
++static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 3,
++
++      .serdes_tbl             = msm8996_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_pcie_serdes_tbl),
++      .tx_tbl                 = msm8996_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_pcie_tx_tbl),
++      .rx_tbl                 = msm8996_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_pcie_rx_tbl),
++      .pcs_tbl                = msm8996_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8996_pcie_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | PLL_READY_GATE_EN,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .mask_com_pcs_ready     = PCS_READY,
++      .phy_status             = PHYSTATUS,
++
++      .has_phy_com_ctrl       = true,
++      .has_lane_rst           = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg msm8996_ufs_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8996_ufs_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_ufs_serdes_tbl),
++      .tx_tbl                 = msm8996_ufs_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_ufs_tx_tbl),
++      .rx_tbl                 = msm8996_ufs_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_ufs_rx_tbl),
++
++      .clk_list               = msm8996_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_ufs_phy_clk_l),
++
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++
++      .regs                   = msm8996_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8996_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_usb3_serdes_tbl),
++      .tx_tbl                 = msm8996_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_usb3_tx_tbl),
++      .rx_tbl                 = msm8996_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_usb3_rx_tbl),
++      .pcs_tbl                = msm8996_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8996_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++};
++
++static const char * const ipq8074_pciephy_clk_l[] = {
++      "aux", "cfg_ahb",
++};
++/* list of resets */
++static const char * const ipq8074_pciephy_reset_l[] = {
++      "phy", "common",
++};
++
++static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq8074_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq8074_pcie_serdes_tbl),
++      .tx_tbl                 = ipq8074_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_tx_tbl),
++      .rx_tbl                 = ipq8074_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_rx_tbl),
++      .pcs_tbl                = ipq8074_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq8074_pcie_pcs_tbl),
++      .clk_list               = ipq8074_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(ipq8074_pciephy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = NULL,
++      .num_vregs              = 0,
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_phy_com_ctrl       = false,
++      .has_lane_rst           = false,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq6018_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq6018_pcie_serdes_tbl),
++      .tx_tbl                 = ipq6018_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(ipq6018_pcie_tx_tbl),
++      .rx_tbl                 = ipq6018_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq6018_pcie_rx_tbl),
++      .pcs_tbl                = ipq6018_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq6018_pcie_pcs_tbl),
++      .clk_list               = ipq8074_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(ipq8074_pciephy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = NULL,
++      .num_vregs              = 0,
++      .regs                   = ipq_pciephy_gen3_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++
++      .has_phy_com_ctrl       = false,
++      .has_lane_rst           = false,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sdm845_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sdm845_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sdm845_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sdm845_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sdm845_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sdm845_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_qmp_pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdm845_qhp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sdm845_qhp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_qhp_pcie_serdes_tbl),
++      .tx_tbl                 = sdm845_qhp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_qhp_pcie_tx_tbl),
++      .rx_tbl                 = sdm845_qhp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_qhp_pcie_rx_tbl),
++      .pcs_tbl                = sdm845_qhp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_qhp_pcie_pcs_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_qhp_pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sm8250_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
++      .serdes_tbl_sec         = sm8250_qmp_gen3x1_pcie_serdes_tbl,
++      .serdes_tbl_num_sec     = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_serdes_tbl),
++      .tx_tbl                 = sm8250_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sm8250_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
++      .rx_tbl_sec             = sm8250_qmp_gen3x1_pcie_rx_tbl,
++      .rx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_rx_tbl),
++      .pcs_tbl                = sm8250_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
++      .pcs_tbl_sec            = sm8250_qmp_gen3x1_pcie_pcs_tbl,
++      .pcs_tbl_num_sec                = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8250_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
++      .pcs_misc_tbl_sec               = sm8250_qmp_gen3x1_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num_sec   = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sm8250_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sm8250_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
++      .tx_tbl_sec             = sm8250_qmp_gen3x2_pcie_tx_tbl,
++      .tx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_tx_tbl),
++      .rx_tbl                 = sm8250_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
++      .rx_tbl_sec             = sm8250_qmp_gen3x2_pcie_rx_tbl,
++      .rx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_rx_tbl),
++      .pcs_tbl                = sm8250_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
++      .pcs_tbl_sec            = sm8250_qmp_gen3x2_pcie_pcs_tbl,
++      .pcs_tbl_num_sec                = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8250_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
++      .pcs_misc_tbl_sec               = sm8250_qmp_gen3x2_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num_sec   = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc7180_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v3_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v3_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v3_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v3_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v3_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v3_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v3_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v3_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v3_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sc7180_usb3dpphy_cfg = {
++      .usb_cfg                = &sc7180_usb3phy_cfg,
++      .dp_cfg                 = &sc7180_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sdm845_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
++      .tx_tbl                 = sdm845_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
++      .rx_tbl                 = sdm845_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
++      .pcs_tbl                = sdm845_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm6115_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm6115_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
++      .rx_tbl                 = sm6115_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
++      .pcs_tbl                = sm6115_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm6115_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++
++      .is_dual_lane_phy       = false,
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8998_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8998_pcie_serdes_tbl),
++      .tx_tbl                 = msm8998_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8998_pcie_tx_tbl),
++      .rx_tbl                 = msm8998_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8998_pcie_rx_tbl),
++      .pcs_tbl                = msm8998_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8998_pcie_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++};
++
++static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8998_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl),
++      .tx_tbl                 = msm8998_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8998_usb3_tx_tbl),
++      .rx_tbl                 = msm8998_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
++      .pcs_tbl                = msm8998_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8150_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8150_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8150_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8150_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8150_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_usb3_tx_tbl),
++      .rx_tbl                 = sm8150_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_usb3_rx_tbl),
++      .pcs_tbl                = sm8150_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sc8180x_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sc8180x_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sc8180x_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sc8180x_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sc8180x_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sc8180x_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sc8180x_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v4_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v4_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v4_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v4_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v4_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v4_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sc8180x_usb3dpphy_cfg = {
++      .usb_cfg                = &sm8150_usb3phy_cfg,
++      .dp_cfg                 = &sc8180x_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8150_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8150_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8150_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8250_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_usb3_tx_tbl),
++      .rx_tbl                 = sm8250_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_usb3_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_sm8250_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8250_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8250_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8250_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v4_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v4_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v4_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v4_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v4_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v4_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sm8250_usb3dpphy_cfg = {
++      .usb_cfg                = &sm8250_usb3phy_cfg,
++      .dp_cfg                 = &sm8250_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sdx55_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx55_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sdx55_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx55_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_sdx55_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sdx55_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdx55_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sdx55_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx55_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sdx55_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx55_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sdx55_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdx55_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sdx55_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sdx55_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS_4_20,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sdx65_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx65_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sdx65_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx65_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_sdx55_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8350_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8350_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8350_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8350_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8350_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8350_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_usb3_tx_tbl),
++      .rx_tbl                 = sm8350_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_usb3_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_sm8250_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8350_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8350_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8350_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8350_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8350_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8350_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8350_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
++      .clk_list               = sm8450_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sm8450_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8450_qmp_gen3x1_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sm8450_qmp_gen3x1_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_serdes_tbl),
++      .tx_tbl                 = sm8450_qmp_gen3x1_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_tx_tbl),
++      .rx_tbl                 = sm8450_qmp_gen3x1_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_rx_tbl),
++      .pcs_tbl                = sm8450_qmp_gen3x1_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8450_qmp_gen3x1_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8450_qmp_gen4x2_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sm8450_qmp_gen4x2_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_serdes_tbl),
++      .tx_tbl                 = sm8450_qmp_gen4x2_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_tx_tbl),
++      .rx_tbl                 = sm8450_qmp_gen4x2_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_rx_tbl),
++      .pcs_tbl                = sm8450_qmp_gen4x2_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8450_qmp_gen4x2_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS_4_20,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qcm2290_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
++      .tx_tbl                 = qcm2290_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_tx_tbl),
++      .rx_tbl                 = qcm2290_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_rx_tbl),
++      .pcs_tbl                = qcm2290_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
++      .clk_list               = qcm2290_usb3phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qcm2290_usb3phy_clk_l),
++      .reset_list             = qcm2290_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(qcm2290_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qcm2290_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static void qcom_qmp_phy_configure_lane(void __iomem *base,
++                                      const unsigned int *regs,
++                                      const struct qmp_phy_init_tbl tbl[],
++                                      int num,
++                                      u8 lane_mask)
++{
++      int i;
++      const struct qmp_phy_init_tbl *t = tbl;
++
++      if (!t)
++              return;
++
++      for (i = 0; i < num; i++, t++) {
++              if (!(t->lane_mask & lane_mask))
++                      continue;
++
++              if (t->in_layout)
++                      writel(t->val, base + regs[t->offset]);
++              else
++                      writel(t->val, base + t->offset);
++      }
++}
++
++static void qcom_qmp_phy_configure(void __iomem *base,
++                                 const unsigned int *regs,
++                                 const struct qmp_phy_init_tbl tbl[],
++                                 int num)
++{
++      qcom_qmp_phy_configure_lane(base, regs, tbl, num, 0xff);
++}
++
++static int qcom_qmp_phy_serdes_init(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
++      int serdes_tbl_num = cfg->serdes_tbl_num;
++      int ret;
++
++      qcom_qmp_phy_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num);
++      if (cfg->serdes_tbl_sec)
++              qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl_sec,
++                                     cfg->serdes_tbl_num_sec);
++
++      if (cfg->type == PHY_TYPE_DP) {
++              switch (dp_opts->link_rate) {
++              case 1620:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_rbr,
++                                             cfg->serdes_tbl_rbr_num);
++                      break;
++              case 2700:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr,
++                                             cfg->serdes_tbl_hbr_num);
++                      break;
++              case 5400:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr2,
++                                             cfg->serdes_tbl_hbr2_num);
++                      break;
++              case 8100:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr3,
++                                             cfg->serdes_tbl_hbr3_num);
++                      break;
++              default:
++                      /* Other link rates aren't supported */
++                      return -EINVAL;
++              }
++      }
++
++
++      if (cfg->has_phy_com_ctrl) {
++              void __iomem *status;
++              unsigned int mask, val;
++
++              qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET], SW_RESET);
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
++                           SERDES_START | PCS_START);
++
++              status = serdes + cfg->regs[QPHY_COM_PCS_READY_STATUS];
++              mask = cfg->mask_com_pcs_ready;
++
++              ret = readl_poll_timeout(status, val, (val & mask), 10,
++                                       PHY_INIT_COMPLETE_TIMEOUT);
++              if (ret) {
++                      dev_err(qmp->dev,
++                              "phy common block init timed-out\n");
++                      return ret;
++              }
++      }
++
++      return 0;
++}
++
++static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy)
++{
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      /* Turn on BIAS current for PHY/PLL */
++      writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX |
++             QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL,
++             qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_LANE_0_1_PWRDN |
++             DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN |
++             DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(QSERDES_V3_COM_BIAS_EN |
++             QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN |
++             QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL |
++             QSERDES_V3_COM_CLKBUF_RX_DRIVE_L,
++             qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0x24, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
++      writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
++      writel(0xbb, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
++      qphy->dp_aux_cfg = 0;
++
++      writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
++             PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
++             PHY_AUX_REQ_ERR_MASK,
++             qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
++}
++
++static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = {
++      { 0x00, 0x0c, 0x15, 0x1a },
++      { 0x02, 0x0e, 0x16, 0xff },
++      { 0x02, 0x11, 0xff, 0xff },
++      { 0x04, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_voltage_swing_hbr3_hbr2[4][4] = {
++      { 0x02, 0x12, 0x16, 0x1a },
++      { 0x09, 0x19, 0x1f, 0xff },
++      { 0x10, 0x1f, 0xff, 0xff },
++      { 0x1f, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = {
++      { 0x00, 0x0c, 0x14, 0x19 },
++      { 0x00, 0x0b, 0x12, 0xff },
++      { 0x00, 0x0b, 0xff, 0xff },
++      { 0x04, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
++      { 0x08, 0x0f, 0x16, 0x1f },
++      { 0x11, 0x1e, 0x1f, 0xff },
++      { 0x19, 0x1f, 0xff, 0xff },
++      { 0x1f, 0xff, 0xff, 0xff }
++};
++
++static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy,
++              unsigned int drv_lvl_reg, unsigned int emp_post_reg)
++{
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      unsigned int v_level = 0, p_level = 0;
++      u8 voltage_swing_cfg, pre_emphasis_cfg;
++      int i;
++
++      for (i = 0; i < dp_opts->lanes; i++) {
++              v_level = max(v_level, dp_opts->voltage[i]);
++              p_level = max(p_level, dp_opts->pre[i]);
++      }
++
++      if (dp_opts->link_rate <= 2700) {
++              voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
++              pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
++      } else {
++              voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr3_hbr2[v_level][p_level];
++              pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr3_hbr2[v_level][p_level];
++      }
++
++      /* TODO: Move check to config check */
++      if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
++              return -EINVAL;
++
++      /* Enable MUX to use Cursor values from these registers */
++      voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
++      pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
++
++      writel(voltage_swing_cfg, qphy->tx + drv_lvl_reg);
++      writel(pre_emphasis_cfg, qphy->tx + emp_post_reg);
++      writel(voltage_swing_cfg, qphy->tx2 + drv_lvl_reg);
++      writel(pre_emphasis_cfg, qphy->tx2 + emp_post_reg);
++
++      return 0;
++}
++
++static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)
++{
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 bias_en, drvr_en;
++
++      if (qcom_qmp_phy_configure_dp_swing(qphy,
++                              QSERDES_V3_TX_TX_DRV_LVL,
++                              QSERDES_V3_TX_TX_EMP_POST1_LVL) < 0)
++              return;
++
++      if (dp_opts->lanes == 1) {
++              bias_en = 0x3e;
++              drvr_en = 0x13;
++      } else {
++              bias_en = 0x3f;
++              drvr_en = 0x10;
++      }
++
++      writel(drvr_en, qphy->tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
++      writel(bias_en, qphy->tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
++      writel(drvr_en, qphy->tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
++      writel(bias_en, qphy->tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
++}
++
++static bool qcom_qmp_phy_configure_dp_mode(struct qmp_phy *qphy)
++{
++      u32 val;
++      bool reverse = false;
++
++      val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++            DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN;
++
++      /*
++       * TODO: Assume orientation is CC1 for now and two lanes, need to
++       * use type-c connector to understand orientation and lanes.
++       *
++       * Otherwise val changes to be like below if this code understood
++       * the orientation of the type-c cable.
++       *
++       * if (lane_cnt == 4 || orientation == ORIENTATION_CC2)
++       *      val |= DP_PHY_PD_CTL_LANE_0_1_PWRDN;
++       * if (lane_cnt == 4 || orientation == ORIENTATION_CC1)
++       *      val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
++       * if (orientation == ORIENTATION_CC2)
++       *      writel(0x4c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
++       */
++      val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
++      writel(val, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(0x5c, qphy->pcs + QSERDES_DP_PHY_MODE);
++
++      return reverse;
++}
++
++static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 phy_vco_div, status;
++      unsigned long pixel_freq;
++
++      qcom_qmp_phy_configure_dp_mode(qphy);
++
++      writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
++      writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              phy_vco_div = 0x1;
++              pixel_freq = 1620000000UL / 2;
++              break;
++      case 2700:
++              phy_vco_div = 0x1;
++              pixel_freq = 2700000000UL / 2;
++              break;
++      case 5400:
++              phy_vco_div = 0x2;
++              pixel_freq = 5400000000UL / 4;
++              break;
++      case 8100:
++              phy_vco_div = 0x0;
++              pixel_freq = 8100000000UL / 6;
++              break;
++      default:
++              /* Other link rates aren't supported */
++              return -EINVAL;
++      }
++      writel(phy_vco_div, qphy->pcs + QSERDES_V3_DP_PHY_VCO_DIV);
++
++      clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
++      clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
++
++      writel(0x04, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      writel(0x20, qphy->serdes + QSERDES_V3_COM_RESETSM_CNTRL);
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V3_COM_C_READY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
++      udelay(2000);
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      return readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000);
++}
++
++/*
++ * We need to calibrate the aux setting here as many times
++ * as the caller tries
++ */
++static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy)
++{
++      static const u8 cfg1_settings[] = { 0x13, 0x23, 0x1d };
++      u8 val;
++
++      qphy->dp_aux_cfg++;
++      qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
++      val = cfg1_settings[qphy->dp_aux_cfg];
++
++      writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++
++      return 0;
++}
++
++static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy)
++{
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      /* Turn on BIAS current for PHY/PLL */
++      writel(0x17, qphy->serdes + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
++      writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
++      writel(0xb7, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
++      qphy->dp_aux_cfg = 0;
++
++      writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
++             PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
++             PHY_AUX_REQ_ERR_MASK,
++             qphy->pcs + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
++}
++
++static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy)
++{
++      /* Program default values before writing proper values */
++      writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
++      writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
++
++      writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++      writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++
++      qcom_qmp_phy_configure_dp_swing(qphy,
++                      QSERDES_V4_TX_TX_DRV_LVL,
++                      QSERDES_V4_TX_TX_EMP_POST1_LVL);
++}
++
++static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 phy_vco_div, status;
++      unsigned long pixel_freq;
++      u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
++      bool reverse;
++
++      writel(0x0f, qphy->pcs + QSERDES_V4_DP_PHY_CFG_1);
++
++      reverse = qcom_qmp_phy_configure_dp_mode(qphy);
++
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++
++      writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL);
++      writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL);
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              phy_vco_div = 0x1;
++              pixel_freq = 1620000000UL / 2;
++              break;
++      case 2700:
++              phy_vco_div = 0x1;
++              pixel_freq = 2700000000UL / 2;
++              break;
++      case 5400:
++              phy_vco_div = 0x2;
++              pixel_freq = 5400000000UL / 4;
++              break;
++      case 8100:
++              phy_vco_div = 0x0;
++              pixel_freq = 8100000000UL / 6;
++              break;
++      default:
++              /* Other link rates aren't supported */
++              return -EINVAL;
++      }
++      writel(phy_vco_div, qphy->pcs + QSERDES_V4_DP_PHY_VCO_DIV);
++
++      clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
++      clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
++
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      writel(0x20, qphy->serdes + QSERDES_V4_COM_RESETSM_CNTRL);
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_C_READY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      /*
++       * At least for 7nm DP PHY this has to be done after enabling link
++       * clock.
++       */
++
++      if (dp_opts->lanes == 1) {
++              bias0_en = reverse ? 0x3e : 0x15;
++              bias1_en = reverse ? 0x15 : 0x3e;
++              drvr0_en = reverse ? 0x13 : 0x10;
++              drvr1_en = reverse ? 0x10 : 0x13;
++      } else if (dp_opts->lanes == 2) {
++              bias0_en = reverse ? 0x3f : 0x15;
++              bias1_en = reverse ? 0x15 : 0x3f;
++              drvr0_en = 0x10;
++              drvr1_en = 0x10;
++      } else {
++              bias0_en = 0x3f;
++              bias1_en = 0x3f;
++              drvr0_en = 0x10;
++              drvr1_en = 0x10;
++      }
++
++      writel(drvr0_en, qphy->tx + QSERDES_V4_TX_HIGHZ_DRVR_EN);
++      writel(bias0_en, qphy->tx + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
++      writel(drvr1_en, qphy->tx2 + QSERDES_V4_TX_HIGHZ_DRVR_EN);
++      writel(bias1_en, qphy->tx2 + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
++
++      writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
++      udelay(2000);
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x0a, qphy->tx + QSERDES_V4_TX_TX_POL_INV);
++      writel(0x0a, qphy->tx2 + QSERDES_V4_TX_TX_POL_INV);
++
++      writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
++      writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
++
++      writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++      writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++
++      return 0;
++}
++
++/*
++ * We need to calibrate the aux setting here as many times
++ * as the caller tries
++ */
++static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy)
++{
++      static const u8 cfg1_settings[] = { 0x20, 0x13, 0x23, 0x1d };
++      u8 val;
++
++      qphy->dp_aux_cfg++;
++      qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
++      val = cfg1_settings[qphy->dp_aux_cfg];
++
++      writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++
++      return 0;
++}
++
++static int qcom_qmp_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
++{
++      const struct phy_configure_opts_dp *dp_opts = &opts->dp;
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      memcpy(&qphy->dp_opts, dp_opts, sizeof(*dp_opts));
++      if (qphy->dp_opts.set_voltages) {
++              cfg->configure_dp_tx(qphy);
++              qphy->dp_opts.set_voltages = 0;
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_dp_phy_calibrate(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      if (cfg->calibrate_dp_phy)
++              return cfg->calibrate_dp_phy(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_com_init(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *dp_com = qmp->dp_com;
++      int ret, i;
++
++      mutex_lock(&qmp->phy_mutex);
++      if (qmp->init_count++) {
++              mutex_unlock(&qmp->phy_mutex);
++              return 0;
++      }
++
++      /* turn on regulator supplies */
++      ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
++      if (ret) {
++              dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
++              goto err_unlock;
++      }
++
++      for (i = 0; i < cfg->num_resets; i++) {
++              ret = reset_control_assert(qmp->resets[i]);
++              if (ret) {
++                      dev_err(qmp->dev, "%s reset assert failed\n",
++                              cfg->reset_list[i]);
++                      goto err_disable_regulators;
++              }
++      }
++
++      for (i = cfg->num_resets - 1; i >= 0; i--) {
++              ret = reset_control_deassert(qmp->resets[i]);
++              if (ret) {
++                      dev_err(qmp->dev, "%s reset deassert failed\n",
++                              qphy->cfg->reset_list[i]);
++                      goto err_assert_reset;
++              }
++      }
++
++      ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
++      if (ret)
++              goto err_assert_reset;
++
++      if (cfg->has_phy_dp_com_ctrl) {
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_POWER_DOWN_CTRL,
++                           SW_PWRDN);
++              /* override hardware control for reset of qmp phy */
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
++                           SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
++                           SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
++
++              /* Default type-c orientation, i.e CC1 */
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_TYPEC_CTRL, 0x02);
++
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_PHY_MODE_CTRL,
++                           USB3_MODE | DP_MODE);
++
++              /* bring both QMP USB and QMP DP PHYs PCS block out of reset */
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
++                           SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
++                           SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
++
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_SWI_CTRL, 0x03);
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
++      }
++
++      if (cfg->has_phy_com_ctrl) {
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
++                           SW_PWRDN);
++      } else {
++              if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
++                      qphy_setbits(pcs,
++                                      cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++                                      cfg->pwrdn_ctrl);
++              else
++                      qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL,
++                                      cfg->pwrdn_ctrl);
++      }
++
++      mutex_unlock(&qmp->phy_mutex);
++
++      return 0;
++
++err_assert_reset:
++      while (++i < cfg->num_resets)
++              reset_control_assert(qmp->resets[i]);
++err_disable_regulators:
++      regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
++err_unlock:
++      mutex_unlock(&qmp->phy_mutex);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_com_exit(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      int i = cfg->num_resets;
++
++      mutex_lock(&qmp->phy_mutex);
++      if (--qmp->init_count) {
++              mutex_unlock(&qmp->phy_mutex);
++              return 0;
++      }
++
++      reset_control_assert(qmp->ufs_reset);
++      if (cfg->has_phy_com_ctrl) {
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
++                           SERDES_START | PCS_START);
++              qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET],
++                           SW_RESET);
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
++                           SW_PWRDN);
++      }
++
++      while (--i >= 0)
++              reset_control_assert(qmp->resets[i]);
++
++      clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++
++      regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
++
++      mutex_unlock(&qmp->phy_mutex);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_init(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      int ret;
++      dev_vdbg(qmp->dev, "Initializing QMP phy\n");
++
++      if (cfg->no_pcs_sw_reset) {
++              /*
++               * Get UFS reset, which is delayed until now to avoid a
++               * circular dependency where UFS needs its PHY, but the PHY
++               * needs this UFS reset.
++               */
++              if (!qmp->ufs_reset) {
++                      qmp->ufs_reset =
++                              devm_reset_control_get_exclusive(qmp->dev,
++                                                               "ufsphy");
++
++                      if (IS_ERR(qmp->ufs_reset)) {
++                              ret = PTR_ERR(qmp->ufs_reset);
++                              dev_err(qmp->dev,
++                                      "failed to get UFS reset: %d\n",
++                                      ret);
++
++                              qmp->ufs_reset = NULL;
++                              return ret;
++                      }
++              }
++
++              ret = reset_control_assert(qmp->ufs_reset);
++              if (ret)
++                      return ret;
++      }
++
++      ret = qcom_qmp_phy_com_init(qphy);
++      if (ret)
++              return ret;
++
++      if (cfg->type == PHY_TYPE_DP)
++              cfg->dp_aux_init(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_power_on(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *tx = qphy->tx;
++      void __iomem *rx = qphy->rx;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++      void __iomem *status;
++      unsigned int mask, val, ready;
++      int ret;
++
++      qcom_qmp_phy_serdes_init(qphy);
++
++      if (cfg->has_lane_rst) {
++              ret = reset_control_deassert(qphy->lane_rst);
++              if (ret) {
++                      dev_err(qmp->dev, "lane%d reset deassert failed\n",
++                              qphy->index);
++                      return ret;
++              }
++      }
++
++      ret = clk_prepare_enable(qphy->pipe_clk);
++      if (ret) {
++              dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
++              goto err_reset_lane;
++      }
++
++      /* Tx, Rx, and PCS configurations */
++      qcom_qmp_phy_configure_lane(tx, cfg->regs,
++                                  cfg->tx_tbl, cfg->tx_tbl_num, 1);
++      if (cfg->tx_tbl_sec)
++              qcom_qmp_phy_configure_lane(tx, cfg->regs, cfg->tx_tbl_sec,
++                                          cfg->tx_tbl_num_sec, 1);
++
++      /* Configuration for other LANE for USB-DP combo PHY */
++      if (cfg->is_dual_lane_phy) {
++              qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
++                                          cfg->tx_tbl, cfg->tx_tbl_num, 2);
++              if (cfg->tx_tbl_sec)
++                      qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
++                                                  cfg->tx_tbl_sec,
++                                                  cfg->tx_tbl_num_sec, 2);
++      }
++
++      /* Configure special DP tx tunings */
++      if (cfg->type == PHY_TYPE_DP)
++              cfg->configure_dp_tx(qphy);
++
++      qcom_qmp_phy_configure_lane(rx, cfg->regs,
++                                  cfg->rx_tbl, cfg->rx_tbl_num, 1);
++      if (cfg->rx_tbl_sec)
++              qcom_qmp_phy_configure_lane(rx, cfg->regs,
++                                          cfg->rx_tbl_sec, cfg->rx_tbl_num_sec, 1);
++
++      if (cfg->is_dual_lane_phy) {
++              qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
++                                          cfg->rx_tbl, cfg->rx_tbl_num, 2);
++              if (cfg->rx_tbl_sec)
++                      qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
++                                                  cfg->rx_tbl_sec,
++                                                  cfg->rx_tbl_num_sec, 2);
++      }
++
++      /* Configure link rate, swing, etc. */
++      if (cfg->type == PHY_TYPE_DP) {
++              cfg->configure_dp_phy(qphy);
++      } else {
++              qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
++              if (cfg->pcs_tbl_sec)
++                      qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl_sec,
++                                             cfg->pcs_tbl_num_sec);
++      }
++
++      ret = reset_control_deassert(qmp->ufs_reset);
++      if (ret)
++              goto err_disable_pipe_clk;
++
++      qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl,
++                             cfg->pcs_misc_tbl_num);
++      if (cfg->pcs_misc_tbl_sec)
++              qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl_sec,
++                                     cfg->pcs_misc_tbl_num_sec);
++
++      /*
++       * Pull out PHY from POWER DOWN state.
++       * This is active low enable signal to power-down PHY.
++       */
++      if(cfg->type == PHY_TYPE_PCIE)
++              qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
++
++      if (cfg->has_pwrdn_delay)
++              usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
++
++      if (cfg->type != PHY_TYPE_DP) {
++              /* Pull PHY out of reset state */
++              if (!cfg->no_pcs_sw_reset)
++                      qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
++              /* start SerDes and Phy-Coding-Sublayer */
++              qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
++
++              if (cfg->type == PHY_TYPE_UFS) {
++                      status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
++                      mask = PCS_READY;
++                      ready = PCS_READY;
++              } else {
++                      status = pcs + cfg->regs[QPHY_PCS_STATUS];
++                      mask = cfg->phy_status;
++                      ready = 0;
++              }
++
++              ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
++                                       PHY_INIT_COMPLETE_TIMEOUT);
++              if (ret) {
++                      dev_err(qmp->dev, "phy initialization timed-out\n");
++                      goto err_disable_pipe_clk;
++              }
++      }
++      return 0;
++
++err_disable_pipe_clk:
++      clk_disable_unprepare(qphy->pipe_clk);
++err_reset_lane:
++      if (cfg->has_lane_rst)
++              reset_control_assert(qphy->lane_rst);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_power_off(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      clk_disable_unprepare(qphy->pipe_clk);
++
++      if (cfg->type == PHY_TYPE_DP) {
++              /* Assert DP PHY power down */
++              writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++      } else {
++              /* PHY reset */
++              if (!cfg->no_pcs_sw_reset)
++                      qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
++
++              /* stop SerDes and Phy-Coding-Sublayer */
++              qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
++
++              /* Put PHY into POWER DOWN state: active low */
++              if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) {
++                      qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++                                   cfg->pwrdn_ctrl);
++              } else {
++                      qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL,
++                                      cfg->pwrdn_ctrl);
++              }
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_phy_exit(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      if (cfg->has_lane_rst)
++              reset_control_assert(qphy->lane_rst);
++
++      qcom_qmp_phy_com_exit(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_enable(struct phy *phy)
++{
++      int ret;
++
++      ret = qcom_qmp_phy_init(phy);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_power_on(phy);
++      if (ret)
++              qcom_qmp_phy_exit(phy);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_disable(struct phy *phy)
++{
++      int ret;
++
++      ret = qcom_qmp_phy_power_off(phy);
++      if (ret)
++              return ret;
++      return qcom_qmp_phy_exit(phy);
++}
++
++static int qcom_qmp_phy_set_mode(struct phy *phy,
++                               enum phy_mode mode, int submode)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++
++      qphy->mode = mode;
++
++      return 0;
++}
++
++static void qcom_qmp_phy_enable_autonomous_mode(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++      u32 intr_mask;
++
++      if (qphy->mode == PHY_MODE_USB_HOST_SS ||
++          qphy->mode == PHY_MODE_USB_DEVICE_SS)
++              intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
++      else
++              intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
++
++      /* Clear any pending interrupts status */
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++      /* Writing 1 followed by 0 clears the interrupt */
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
++                   ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);
++
++      /* Enable required PHY autonomous mode interrupts */
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
++
++      /* Enable i/o clamp_n for autonomous mode */
++      if (pcs_misc)
++              qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
++}
++
++static void qcom_qmp_phy_disable_autonomous_mode(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++
++      /* Disable i/o clamp_n on resume for normal mode */
++      if (pcs_misc)
++              qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
++
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
++                   ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
++
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++      /* Writing 1 followed by 0 clears the interrupt */
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++}
++
++static int __maybe_unused qcom_qmp_phy_runtime_suspend(struct device *dev)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct qmp_phy *qphy = qmp->phys[0];
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qphy->mode);
++
++      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
++      if (cfg->type != PHY_TYPE_USB3)
++              return 0;
++
++      if (!qmp->init_count) {
++              dev_vdbg(dev, "PHY not initialized, bailing out\n");
++              return 0;
++      }
++
++      qcom_qmp_phy_enable_autonomous_mode(qphy);
++
++      clk_disable_unprepare(qphy->pipe_clk);
++      clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++
++      return 0;
++}
++
++static int __maybe_unused qcom_qmp_phy_runtime_resume(struct device *dev)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct qmp_phy *qphy = qmp->phys[0];
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      int ret = 0;
++
++      dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qphy->mode);
++
++      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
++      if (cfg->type != PHY_TYPE_USB3)
++              return 0;
++
++      if (!qmp->init_count) {
++              dev_vdbg(dev, "PHY not initialized, bailing out\n");
++              return 0;
++      }
++
++      ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
++      if (ret)
++              return ret;
++
++      ret = clk_prepare_enable(qphy->pipe_clk);
++      if (ret) {
++              dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
++              clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++              return ret;
++      }
++
++      qcom_qmp_phy_disable_autonomous_mode(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int num = cfg->num_vregs;
++      int i;
++
++      qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
++      if (!qmp->vregs)
++              return -ENOMEM;
++
++      for (i = 0; i < num; i++)
++              qmp->vregs[i].supply = cfg->vreg_list[i];
++
++      return devm_regulator_bulk_get(dev, num, qmp->vregs);
++}
++
++static int qcom_qmp_phy_reset_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int i;
++
++      qmp->resets = devm_kcalloc(dev, cfg->num_resets,
++                                 sizeof(*qmp->resets), GFP_KERNEL);
++      if (!qmp->resets)
++              return -ENOMEM;
++
++      for (i = 0; i < cfg->num_resets; i++) {
++              struct reset_control *rst;
++              const char *name = cfg->reset_list[i];
++
++              rst = devm_reset_control_get_exclusive(dev, name);
++              if (IS_ERR(rst)) {
++                      dev_err(dev, "failed to get %s reset\n", name);
++                      return PTR_ERR(rst);
++              }
++              qmp->resets[i] = rst;
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_phy_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int num = cfg->num_clks;
++      int i;
++
++      qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
++      if (!qmp->clks)
++              return -ENOMEM;
++
++      for (i = 0; i < num; i++)
++              qmp->clks[i].id = cfg->clk_list[i];
++
++      return devm_clk_bulk_get(dev, num, qmp->clks);
++}
++
++static void phy_clk_release_provider(void *res)
++{
++      of_clk_del_provider(res);
++}
++
++/*
++ * Register a fixed rate pipe clock.
++ *
++ * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
++ * controls it. The <s>_pipe_clk coming out of the GCC is requested
++ * by the PHY driver for its operations.
++ * We register the <s>_pipe_clksrc here. The gcc driver takes care
++ * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
++ * Below picture shows this relationship.
++ *
++ *         +---------------+
++ *         |   PHY block   |<<---------------------------------------+
++ *         |               |                                         |
++ *         |   +-------+   |                   +-----+               |
++ *   I/P---^-->|  PLL  |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
++ *    clk  |   +-------+   |                   +-----+
++ *         +---------------+
++ */
++static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
++{
++      struct clk_fixed_rate *fixed;
++      struct clk_init_data init = { };
++      int ret;
++
++      ret = of_property_read_string(np, "clock-output-names", &init.name);
++      if (ret) {
++              dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
++              return ret;
++      }
++
++      fixed = devm_kzalloc(qmp->dev, sizeof(*fixed), GFP_KERNEL);
++      if (!fixed)
++              return -ENOMEM;
++
++      init.ops = &clk_fixed_rate_ops;
++
++      /* controllers using QMP phys use 125MHz pipe clock interface */
++      fixed->fixed_rate = 125000000;
++      fixed->hw.init = &init;
++
++      ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
++      if (ret)
++              return ret;
++
++      ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
++      if (ret)
++              return ret;
++
++      /*
++       * Roll a devm action because the clock provider is the child node, but
++       * the child node is not actually a device.
++       */
++      return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
++}
++
++/*
++ * Display Port PLL driver block diagram for branch clocks
++ *
++ *              +------------------------------+
++ *              |         DP_VCO_CLK           |
++ *              |                              |
++ *              |    +-------------------+     |
++ *              |    |   (DP PLL/VCO)    |     |
++ *              |    +---------+---------+     |
++ *              |              v               |
++ *              |   +----------+-----------+   |
++ *              |   | hsclk_divsel_clk_src |   |
++ *              |   +----------+-----------+   |
++ *              +------------------------------+
++ *                              |
++ *          +---------<---------v------------>----------+
++ *          |                                           |
++ * +--------v----------------+                          |
++ * |    dp_phy_pll_link_clk  |                          |
++ * |     link_clk            |                          |
++ * +--------+----------------+                          |
++ *          |                                           |
++ *          |                                           |
++ *          v                                           v
++ * Input to DISPCC block                                |
++ * for link clk, crypto clk                             |
++ * and interface clock                                  |
++ *                                                      |
++ *                                                      |
++ *      +--------<------------+-----------------+---<---+
++ *      |                     |                 |
++ * +----v---------+  +--------v-----+  +--------v------+
++ * | vco_divided  |  | vco_divided  |  | vco_divided   |
++ * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
++ * |              |  |              |  |               |
++ * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
++ * +-------+------+  +-----+--------+  +--------+------+
++ *         |                 |                  |
++ *         v---->----------v-------------<------v
++ *                         |
++ *              +----------+-----------------+
++ *              |   dp_phy_pll_vco_div_clk   |
++ *              +---------+------------------+
++ *                        |
++ *                        v
++ *              Input to DISPCC block
++ *              for DP pixel clock
++ *
++ */
++static int qcom_qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
++                                              struct clk_rate_request *req)
++{
++      switch (req->rate) {
++      case 1620000000UL / 2:
++      case 2700000000UL / 2:
++      /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
++              return 0;
++      default:
++              return -EINVAL;
++      }
++}
++
++static unsigned long
++qcom_qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
++{
++      const struct qmp_phy_dp_clks *dp_clks;
++      const struct qmp_phy *qphy;
++      const struct phy_configure_opts_dp *dp_opts;
++
++      dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_pixel_hw);
++      qphy = dp_clks->qphy;
++      dp_opts = &qphy->dp_opts;
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              return 1620000000UL / 2;
++      case 2700:
++              return 2700000000UL / 2;
++      case 5400:
++              return 5400000000UL / 4;
++      case 8100:
++              return 8100000000UL / 6;
++      default:
++              return 0;
++      }
++}
++
++static const struct clk_ops qcom_qmp_dp_pixel_clk_ops = {
++      .determine_rate = qcom_qmp_dp_pixel_clk_determine_rate,
++      .recalc_rate = qcom_qmp_dp_pixel_clk_recalc_rate,
++};
++
++static int qcom_qmp_dp_link_clk_determine_rate(struct clk_hw *hw,
++                                             struct clk_rate_request *req)
++{
++      switch (req->rate) {
++      case 162000000:
++      case 270000000:
++      case 540000000:
++      case 810000000:
++              return 0;
++      default:
++              return -EINVAL;
++      }
++}
++
++static unsigned long
++qcom_qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
++{
++      const struct qmp_phy_dp_clks *dp_clks;
++      const struct qmp_phy *qphy;
++      const struct phy_configure_opts_dp *dp_opts;
++
++      dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_link_hw);
++      qphy = dp_clks->qphy;
++      dp_opts = &qphy->dp_opts;
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++      case 2700:
++      case 5400:
++      case 8100:
++              return dp_opts->link_rate * 100000;
++      default:
++              return 0;
++      }
++}
++
++static const struct clk_ops qcom_qmp_dp_link_clk_ops = {
++      .determine_rate = qcom_qmp_dp_link_clk_determine_rate,
++      .recalc_rate = qcom_qmp_dp_link_clk_recalc_rate,
++};
++
++static struct clk_hw *
++qcom_qmp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *data)
++{
++      struct qmp_phy_dp_clks *dp_clks = data;
++      unsigned int idx = clkspec->args[0];
++
++      if (idx >= 2) {
++              pr_err("%s: invalid index %u\n", __func__, idx);
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (idx == 0)
++              return &dp_clks->dp_link_hw;
++
++      return &dp_clks->dp_pixel_hw;
++}
++
++static int phy_dp_clks_register(struct qcom_qmp *qmp, struct qmp_phy *qphy,
++                              struct device_node *np)
++{
++      struct clk_init_data init = { };
++      struct qmp_phy_dp_clks *dp_clks;
++      char name[64];
++      int ret;
++
++      dp_clks = devm_kzalloc(qmp->dev, sizeof(*dp_clks), GFP_KERNEL);
++      if (!dp_clks)
++              return -ENOMEM;
++
++      dp_clks->qphy = qphy;
++      qphy->dp_clks = dp_clks;
++
++      snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
++      init.ops = &qcom_qmp_dp_link_clk_ops;
++      init.name = name;
++      dp_clks->dp_link_hw.init = &init;
++      ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_link_hw);
++      if (ret)
++              return ret;
++
++      snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
++      init.ops = &qcom_qmp_dp_pixel_clk_ops;
++      init.name = name;
++      dp_clks->dp_pixel_hw.init = &init;
++      ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_pixel_hw);
++      if (ret)
++              return ret;
++
++      ret = of_clk_add_hw_provider(np, qcom_qmp_dp_clks_hw_get, dp_clks);
++      if (ret)
++              return ret;
++
++      /*
++       * Roll a devm action because the clock provider is the child node, but
++       * the child node is not actually a device.
++       */
++      return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
++}
++
++static const struct phy_ops qcom_qmp_phy_gen_ops = {
++      .init           = qcom_qmp_phy_enable,
++      .exit           = qcom_qmp_phy_disable,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static const struct phy_ops qcom_qmp_phy_dp_ops = {
++      .init           = qcom_qmp_phy_init,
++      .configure      = qcom_qmp_dp_phy_configure,
++      .power_on       = qcom_qmp_phy_power_on,
++      .calibrate      = qcom_qmp_dp_phy_calibrate,
++      .power_off      = qcom_qmp_phy_power_off,
++      .exit           = qcom_qmp_phy_exit,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static const struct phy_ops qcom_qmp_pcie_ufs_ops = {
++      .power_on       = qcom_qmp_phy_enable,
++      .power_off      = qcom_qmp_phy_disable,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static void qcom_qmp_reset_control_put(void *data)
++{
++      reset_control_put(data);
++}
++
++static
++int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id,
++                      void __iomem *serdes, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct phy *generic_phy;
++      struct qmp_phy *qphy;
++      const struct phy_ops *ops;
++      char prop_name[MAX_PROP_NAME];
++      int ret;
++
++      qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
++      if (!qphy)
++              return -ENOMEM;
++
++      qphy->cfg = cfg;
++      qphy->serdes = serdes;
++      /*
++       * Get memory resources for each phy lane:
++       * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
++       * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
++       * For single lane PHYs: pcs_misc (optional) -> 3.
++       */
++      qphy->tx = of_iomap(np, 0);
++      if (!qphy->tx)
++              return -ENOMEM;
++
++      qphy->rx = of_iomap(np, 1);
++      if (!qphy->rx)
++              return -ENOMEM;
++
++      qphy->pcs = of_iomap(np, 2);
++      if (!qphy->pcs)
++              return -ENOMEM;
++
++      /*
++       * If this is a dual-lane PHY, then there should be registers for the
++       * second lane. Some old device trees did not specify this, so fall
++       * back to old legacy behavior of assuming they can be reached at an
++       * offset from the first lane.
++       */
++      if (cfg->is_dual_lane_phy) {
++              qphy->tx2 = of_iomap(np, 3);
++              qphy->rx2 = of_iomap(np, 4);
++              if (!qphy->tx2 || !qphy->rx2) {
++                      dev_warn(dev,
++                               "Underspecified device tree, falling back to legacy register regions\n");
++
++                      /* In the old version, pcs_misc is at index 3. */
++                      qphy->pcs_misc = qphy->tx2;
++                      qphy->tx2 = qphy->tx + QMP_PHY_LEGACY_LANE_STRIDE;
++                      qphy->rx2 = qphy->rx + QMP_PHY_LEGACY_LANE_STRIDE;
++
++              } else {
++                      qphy->pcs_misc = of_iomap(np, 5);
++              }
++
++      } else {
++              qphy->pcs_misc = of_iomap(np, 3);
++      }
++
++      if (!qphy->pcs_misc)
++              dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
++
++      /*
++       * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3
++       * based phys, so they essentially have pipe clock. So,
++       * we return error in case phy is USB3 or PIPE type.
++       * Otherwise, we initialize pipe clock to NULL for
++       * all phys that don't need this.
++       */
++      snprintf(prop_name, sizeof(prop_name), "pipe%d", id);
++      qphy->pipe_clk = devm_get_clk_from_child(dev, np, prop_name);
++      if (IS_ERR(qphy->pipe_clk)) {
++              if (cfg->type == PHY_TYPE_PCIE ||
++                  cfg->type == PHY_TYPE_USB3) {
++                      ret = PTR_ERR(qphy->pipe_clk);
++                      if (ret != -EPROBE_DEFER)
++                              dev_err(dev,
++                                      "failed to get lane%d pipe_clk, %d\n",
++                                      id, ret);
++                      return ret;
++              }
++              qphy->pipe_clk = NULL;
++      }
++
++      /* Get lane reset, if any */
++      if (cfg->has_lane_rst) {
++              snprintf(prop_name, sizeof(prop_name), "lane%d", id);
++              qphy->lane_rst = of_reset_control_get_exclusive(np, prop_name);
++              if (IS_ERR(qphy->lane_rst)) {
++                      dev_err(dev, "failed to get lane%d reset\n", id);
++                      return PTR_ERR(qphy->lane_rst);
++              }
++              ret = devm_add_action_or_reset(dev, qcom_qmp_reset_control_put,
++                                             qphy->lane_rst);
++              if (ret)
++                      return ret;
++      }
++
++      if (cfg->type == PHY_TYPE_UFS || cfg->type == PHY_TYPE_PCIE)
++              ops = &qcom_qmp_pcie_ufs_ops;
++      else if (cfg->type == PHY_TYPE_DP)
++              ops = &qcom_qmp_phy_dp_ops;
++      else
++              ops = &qcom_qmp_phy_gen_ops;
++
++      generic_phy = devm_phy_create(dev, np, ops);
++      if (IS_ERR(generic_phy)) {
++              ret = PTR_ERR(generic_phy);
++              dev_err(dev, "failed to create qphy %d\n", ret);
++              return ret;
++      }
++
++      qphy->phy = generic_phy;
++      qphy->index = id;
++      qphy->qmp = qmp;
++      qmp->phys[id] = qphy;
++      phy_set_drvdata(generic_phy, qphy);
++
++      return 0;
++}
++
++static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
++      {
++              .compatible = "qcom,ipq8074-qmp-usb3-phy",
++              .data = &ipq8074_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-pcie-phy",
++              .data = &msm8996_pciephy_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-ufs-phy",
++              .data = &msm8996_ufs_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-usb3-phy",
++              .data = &msm8996_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-pcie-phy",
++              .data = &msm8998_pciephy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,ipq8074-qmp-pcie-phy",
++              .data = &ipq8074_pciephy_cfg,
++      }, {
++              .compatible = "qcom,ipq6018-qmp-pcie-phy",
++              .data = &ipq6018_pciephy_cfg,
++      }, {
++              .compatible = "qcom,ipq6018-qmp-usb3-phy",
++              .data = &ipq8074_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc7180-qmp-usb3-phy",
++              .data = &sc7180_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sc8180x-qmp-pcie-phy",
++              .data = &sc8180x_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sc8280xp-qmp-ufs-phy",
++              .data = &sm8350_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-usb3-phy",
++              .data = &sm8150_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sdm845-qhp-pcie-phy",
++              .data = &sdm845_qhp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-pcie-phy",
++              .data = &sdm845_qmp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-usb3-phy",
++              .data = &qmp_v3_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-usb3-uni-phy",
++              .data = &qmp_v3_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-usb3-phy",
++              .data = &msm8998_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm6115-qmp-ufs-phy",
++              .data = &sm6115_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm6350-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-usb3-phy",
++              .data = &sm8150_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-usb3-uni-phy",
++              .data = &sm8150_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-phy",
++              .data = &sm8250_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-uni-phy",
++              .data = &sm8250_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy",
++              .data = &sm8250_qmp_gen3x1_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-gen3x2-pcie-phy",
++              .data = &sm8250_qmp_gen3x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-ufs-phy",
++              .data = &sm8350_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-modem-pcie-phy",
++              .data = &sm8250_qmp_gen3x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdx55-qmp-pcie-phy",
++              .data = &sdx55_qmp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdx55-qmp-usb3-uni-phy",
++              .data = &sdx55_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sdx65-qmp-usb3-uni-phy",
++              .data = &sdx65_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-usb3-phy",
++              .data = &sm8350_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-usb3-uni-phy",
++              .data = &sm8350_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-gen3x1-pcie-phy",
++              .data = &sm8450_qmp_gen3x1_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-gen4x2-pcie-phy",
++              .data = &sm8450_qmp_gen4x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-ufs-phy",
++              .data = &sm8450_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-usb3-phy",
++              .data = &sm8350_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,qcm2290-qmp-usb3-phy",
++              .data = &qcm2290_usb3phy_cfg,
++      },
++      { },
++};
++MODULE_DEVICE_TABLE(of, qcom_qmp_phy_of_match_table);
++
++static const struct of_device_id qcom_qmp_combo_phy_of_match_table[] = {
++      {
++              .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
++              .data = &sc7180_usb3dpphy_cfg,
++      },
++      {
++              .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
++              .data = &sm8250_usb3dpphy_cfg,
++      },
++      {
++              .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
++              .data = &sc8180x_usb3dpphy_cfg,
++      },
++      { }
++};
++
++static const struct dev_pm_ops qcom_qmp_phy_pm_ops = {
++      SET_RUNTIME_PM_OPS(qcom_qmp_phy_runtime_suspend,
++                         qcom_qmp_phy_runtime_resume, NULL)
++};
++
++static int qcom_qmp_phy_probe(struct platform_device *pdev)
++{
++      struct qcom_qmp *qmp;
++      struct device *dev = &pdev->dev;
++      struct device_node *child;
++      struct phy_provider *phy_provider;
++      void __iomem *serdes;
++      void __iomem *usb_serdes;
++      void __iomem *dp_serdes = NULL;
++      const struct qmp_phy_combo_cfg *combo_cfg = NULL;
++      const struct qmp_phy_cfg *cfg = NULL;
++      const struct qmp_phy_cfg *usb_cfg = NULL;
++      const struct qmp_phy_cfg *dp_cfg = NULL;
++      int num, id, expected_phys;
++      int ret;
++
++      qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
++      if (!qmp)
++              return -ENOMEM;
++
++      qmp->dev = dev;
++      dev_set_drvdata(dev, qmp);
++
++      /* Get the specific init parameters of QMP phy */
++      cfg = of_device_get_match_data(dev);
++      if (!cfg) {
++              const struct of_device_id *match;
++
++              match = of_match_device(qcom_qmp_combo_phy_of_match_table, dev);
++              if (!match)
++                      return -EINVAL;
++
++              combo_cfg = match->data;
++              if (!combo_cfg)
++                      return -EINVAL;
++
++              usb_cfg = combo_cfg->usb_cfg;
++              cfg = usb_cfg; /* Setup clks and regulators */
++      }
++
++      /* per PHY serdes; usually located at base address */
++      usb_serdes = serdes = devm_platform_ioremap_resource(pdev, 0);
++      if (IS_ERR(serdes))
++              return PTR_ERR(serdes);
++
++      /* per PHY dp_com; if PHY has dp_com control block */
++      if (combo_cfg || cfg->has_phy_dp_com_ctrl) {
++              qmp->dp_com = devm_platform_ioremap_resource(pdev, 1);
++              if (IS_ERR(qmp->dp_com))
++                      return PTR_ERR(qmp->dp_com);
++      }
++
++      if (combo_cfg) {
++              /* Only two serdes for combo PHY */
++              dp_serdes = devm_platform_ioremap_resource(pdev, 2);
++              if (IS_ERR(dp_serdes))
++                      return PTR_ERR(dp_serdes);
++
++              dp_cfg = combo_cfg->dp_cfg;
++              expected_phys = 2;
++      } else {
++              expected_phys = cfg->nlanes;
++      }
++
++      mutex_init(&qmp->phy_mutex);
++
++      ret = qcom_qmp_phy_clk_init(dev, cfg);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_reset_init(dev, cfg);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_vreg_init(dev, cfg);
++      if (ret) {
++              if (ret != -EPROBE_DEFER)
++                      dev_err(dev, "failed to get regulator supplies: %d\n",
++                              ret);
++              return ret;
++      }
++
++      num = of_get_available_child_count(dev->of_node);
++      /* do we have a rogue child node ? */
++      if (num > expected_phys)
++              return -EINVAL;
++
++      qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
++      if (!qmp->phys)
++              return -ENOMEM;
++
++      pm_runtime_set_active(dev);
++      pm_runtime_enable(dev);
++      /*
++       * Prevent runtime pm from being ON by default. Users can enable
++       * it using power/control in sysfs.
++       */
++      pm_runtime_forbid(dev);
++
++      id = 0;
++      for_each_available_child_of_node(dev->of_node, child) {
++              if (of_node_name_eq(child, "dp-phy")) {
++                      cfg = dp_cfg;
++                      serdes = dp_serdes;
++              } else if (of_node_name_eq(child, "usb3-phy")) {
++                      cfg = usb_cfg;
++                      serdes = usb_serdes;
++              }
++
++              /* Create per-lane phy */
++              ret = qcom_qmp_phy_create(dev, child, id, serdes, cfg);
++              if (ret) {
++                      dev_err(dev, "failed to create lane%d phy, %d\n",
++                              id, ret);
++                      goto err_node_put;
++              }
++
++              /*
++               * Register the pipe clock provided by phy.
++               * See function description to see details of this pipe clock.
++               */
++              if (cfg->type == PHY_TYPE_USB3 || cfg->type == PHY_TYPE_PCIE) {
++                      ret = phy_pipe_clk_register(qmp, child);
++                      if (ret) {
++                              dev_err(qmp->dev,
++                                      "failed to register pipe clock source\n");
++                              goto err_node_put;
++                      }
++              } else if (cfg->type == PHY_TYPE_DP) {
++                      ret = phy_dp_clks_register(qmp, qmp->phys[id], child);
++                      if (ret) {
++                              dev_err(qmp->dev,
++                                      "failed to register DP clock source\n");
++                              goto err_node_put;
++                      }
++              }
++              id++;
++      }
++
++      phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
++      if (!IS_ERR(phy_provider))
++              dev_info(dev, "Registered Qcom-QMP phy\n");
++      else
++              pm_runtime_disable(dev);
++
++      return PTR_ERR_OR_ZERO(phy_provider);
++
++err_node_put:
++      pm_runtime_disable(dev);
++      of_node_put(child);
++      return ret;
++}
++
++static struct platform_driver qcom_qmp_phy_driver = {
++      .probe          = qcom_qmp_phy_probe,
++      .driver = {
++              .name   = "qcom-qmp-phy",
++              .pm     = &qcom_qmp_phy_pm_ops,
++              .of_match_table = qcom_qmp_phy_of_match_table,
++      },
++};
++
++module_platform_driver(qcom_qmp_phy_driver);
++
++MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
++MODULE_DESCRIPTION("Qualcomm QMP PHY driver");
++MODULE_LICENSE("GPL v2");
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
+new file mode 100644
+index 000000000000..c7309e981bfb
+--- /dev/null
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
+@@ -0,0 +1,6350 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++
++#include <dt-bindings/phy/phy.h>
++
++#include "phy-qcom-qmp.h"
++
++/* QPHY_SW_RESET bit */
++#define SW_RESET                              BIT(0)
++/* QPHY_POWER_DOWN_CONTROL */
++#define SW_PWRDN                              BIT(0)
++#define REFCLK_DRV_DSBL                               BIT(1)
++/* QPHY_START_CONTROL bits */
++#define SERDES_START                          BIT(0)
++#define PCS_START                             BIT(1)
++#define PLL_READY_GATE_EN                     BIT(3)
++/* QPHY_PCS_STATUS bit */
++#define PHYSTATUS                             BIT(6)
++#define PHYSTATUS_4_20                                BIT(7)
++/* QPHY_PCS_READY_STATUS & QPHY_COM_PCS_READY_STATUS bit */
++#define PCS_READY                             BIT(0)
++
++/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
++/* DP PHY soft reset */
++#define SW_DPPHY_RESET                                BIT(0)
++/* mux to select DP PHY reset control, 0:HW control, 1: software reset */
++#define SW_DPPHY_RESET_MUX                    BIT(1)
++/* USB3 PHY soft reset */
++#define SW_USB3PHY_RESET                      BIT(2)
++/* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
++#define SW_USB3PHY_RESET_MUX                  BIT(3)
++
++/* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
++#define USB3_MODE                             BIT(0) /* enables USB3 mode */
++#define DP_MODE                                       BIT(1) /* enables DP mode */
++
++/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
++#define ARCVR_DTCT_EN                         BIT(0)
++#define ALFPS_DTCT_EN                         BIT(1)
++#define ARCVR_DTCT_EVENT_SEL                  BIT(4)
++
++/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
++#define IRQ_CLEAR                             BIT(0)
++
++/* QPHY_PCS_LFPS_RXTERM_IRQ_STATUS register bits */
++#define RCVR_DETECT                           BIT(0)
++
++/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
++#define CLAMP_EN                              BIT(0) /* enables i/o clamp_n */
++
++#define PHY_INIT_COMPLETE_TIMEOUT             10000
++#define POWER_DOWN_DELAY_US_MIN                       10
++#define POWER_DOWN_DELAY_US_MAX                       11
++
++#define MAX_PROP_NAME                         32
++
++/* Define the assumed distance between lanes for underspecified device trees. */
++#define QMP_PHY_LEGACY_LANE_STRIDE            0x400
++
++struct qmp_phy_init_tbl {
++      unsigned int offset;
++      unsigned int val;
++      /*
++       * register part of layout ?
++       * if yes, then offset gives index in the reg-layout
++       */
++      bool in_layout;
++      /*
++       * mask of lanes for which this register is written
++       * for cases when second lane needs different values
++       */
++      u8 lane_mask;
++};
++
++#define QMP_PHY_INIT_CFG(o, v)                \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .lane_mask = 0xff,      \
++      }
++
++#define QMP_PHY_INIT_CFG_L(o, v)      \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .in_layout = true,      \
++              .lane_mask = 0xff,      \
++      }
++
++#define QMP_PHY_INIT_CFG_LANE(o, v, l)        \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .lane_mask = l,         \
++      }
++
++/* set of registers with offsets different per-PHY */
++enum qphy_reg_layout {
++      /* Common block control registers */
++      QPHY_COM_SW_RESET,
++      QPHY_COM_POWER_DOWN_CONTROL,
++      QPHY_COM_START_CONTROL,
++      QPHY_COM_PCS_READY_STATUS,
++      /* PCS registers */
++      QPHY_PLL_LOCK_CHK_DLY_TIME,
++      QPHY_FLL_CNTRL1,
++      QPHY_FLL_CNTRL2,
++      QPHY_FLL_CNT_VAL_L,
++      QPHY_FLL_CNT_VAL_H_TOL,
++      QPHY_FLL_MAN_CODE,
++      QPHY_SW_RESET,
++      QPHY_START_CTRL,
++      QPHY_PCS_READY_STATUS,
++      QPHY_PCS_STATUS,
++      QPHY_PCS_AUTONOMOUS_MODE_CTRL,
++      QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
++      QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
++      QPHY_PCS_POWER_DOWN_CONTROL,
++      /* PCS_MISC registers */
++      QPHY_PCS_MISC_TYPEC_CTRL,
++      /* Keep last to ensure regs_layout arrays are properly initialized */
++      QPHY_LAYOUT_SIZE
++};
++
++static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x168,
++};
++
++static const unsigned int ipq_pciephy_gen3_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                         = 0x00,
++      [QPHY_START_CTRL]                       = 0x44,
++      [QPHY_PCS_STATUS]                       = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]           = 0x40,
++};
++
++static const unsigned int pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_COM_SW_RESET]             = 0x400,
++      [QPHY_COM_POWER_DOWN_CONTROL]   = 0x404,
++      [QPHY_COM_START_CONTROL]        = 0x408,
++      [QPHY_COM_PCS_READY_STATUS]     = 0x448,
++      [QPHY_PLL_LOCK_CHK_DLY_TIME]    = 0xa8,
++      [QPHY_FLL_CNTRL1]               = 0xc4,
++      [QPHY_FLL_CNTRL2]               = 0xc8,
++      [QPHY_FLL_CNT_VAL_L]            = 0xcc,
++      [QPHY_FLL_CNT_VAL_H_TOL]        = 0xd0,
++      [QPHY_FLL_MAN_CODE]             = 0xd4,
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++};
++
++static const unsigned int usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_FLL_CNTRL1]               = 0xc0,
++      [QPHY_FLL_CNTRL2]               = 0xc4,
++      [QPHY_FLL_CNT_VAL_L]            = 0xc8,
++      [QPHY_FLL_CNT_VAL_H_TOL]        = 0xcc,
++      [QPHY_FLL_MAN_CODE]             = 0xd0,
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x17c,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d4,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0d8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178,
++};
++
++static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0dc,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
++};
++
++static const unsigned int sdm845_qmp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++};
++
++static const unsigned int sdm845_qhp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x2ac,
++};
++
++static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x308,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x314,
++};
++
++static const unsigned int qmp_v4_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x608,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x614,
++};
++
++static const unsigned int sm8350_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x1008,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x1014,
++};
++
++static const unsigned int qcm2290_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x04,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0xd8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0xdc,
++      [QPHY_PCS_STATUS]               = 0x174,
++      [QPHY_PCS_MISC_TYPEC_CTRL]      = 0x00,
++};
++
++static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x160,
++};
++
++static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x168,
++};
++
++static const unsigned int sm8250_pcie_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++};
++
++static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = QPHY_V4_PCS_UFS_PHY_START,
++      [QPHY_PCS_READY_STATUS]         = QPHY_V4_PCS_UFS_READY_STATUS,
++      [QPHY_SW_RESET]                 = QPHY_V4_PCS_UFS_SW_RESET,
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      /* PLL and Loop filter settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      /* SSC settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x0),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x40),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x19),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_RX_IDLE_DTCT_CNTRL, 0x4c),
++      QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++
++      QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x05),
++
++      QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x05),
++      QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG4, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG1, 0xa3),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0x0e),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x7e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x15),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x40),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x99),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x04),
++      /* PLL and Loop filter settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      /* SSC settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xbb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL2, 0x03),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_H_TOL, 0x42),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_MAN_CODE, 0x85),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG2, 0x08),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x29),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x53),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_TX0_LANE_MODE_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_TX0_RCV_DETECT_LVL_2, 0x12),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_GAIN, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0x61),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_LOW, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH2, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH3, 0xd3),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH4, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_LOW, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_DFE_EN_TIMER, 0x04),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL1, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(PCS_COM_G12S1_TXDEEMPH_M3P5DB, 0x10),
++      QMP_PHY_INIT_CFG(PCS_COM_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_RX_DCC_CAL_CONFIG, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_EQ_CONFIG5, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
++      QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
++      QMP_PHY_INIT_CFG(PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++      QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG1, 0x11),
++      QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_POST, 0x58),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0xf),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0xf),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x3),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0xD),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xD04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0xb),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x6),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_TX_EMP_POST1_LVL, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_TX_SLEW_CNTL, 0x0a),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x4),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x4),
++      QMP_PHY_INIT_CFG(QPHY_OSC_DTCT_ACTIONS, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x40),
++      QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x73),
++      QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_LVL, 0x99),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0xe),
++      QMP_PHY_INIT_CFG_L(QPHY_SW_RESET, 0x0),
++      QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x007),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x7e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x15),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_01, 0x59),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x40),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE, 0x04),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xbb),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG4, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_CONFIG2, 0x52),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG2, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG4, 0x1a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG5, 0x06),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SYSCLK_EN_SEL, 0x27),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE2, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BIAS_EN_CKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CLK_ENABLE1, 0xb0),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP1_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP2_MODE0, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_RESTRIM_CTRL2, 0x05),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VCO_TUNE_MAP, 0x10),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CLK_SELECT, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_HSCLK_SEL1, 0x30),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORECLK_DIV, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORE_CLK_EN, 0x73),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CMN_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SVS_MODE_CLK_SEL, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VREGCLK_DIV1, 0x22),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VREGCLK_DIV2, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BGV_TRIM, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BG_CTRL, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL0, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_TAP_EN, 0x0d),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_TX_BAND_MODE, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_LANE_MODE, 0x1a),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PARALLEL_RATE, 0x2f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE0, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE1, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE2, 0x1b),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PREAMP_CTRL_MODE1, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PREAMP_CTRL_MODE2, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE0, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE1, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE2, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_THRESH_DFE, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CGA_THRESH_DFE, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXENGINE_EN0, 0x12),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_TRAIN_TIME, 0x25),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_DFE_OVRLP_TIME, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_REFRESH_TIME, 0x05),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_ENABLE_TIME, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_VGA_GAIN, 0x26),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_GAIN, 0x12),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EQ_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_OFFSET_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PRE_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EQ_INTVAL, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EDAC_INITVAL, 0x28),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_INITB0, 0x7f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_INITB1, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RCVRDONE_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_CTRL, 0x70),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE0, 0x8b),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE2, 0x0a),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE2, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_BAND, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE0, 0x5c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE1, 0x3e),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE2, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_ENABLES, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_CNTRL, 0xa0),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_DEGLITCH_CNTRL, 0x08),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DCC_GAIN, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_EN_SIGNAL, 0xc3),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PSM_RX_EN_CAL, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_MISC_CNTRL0, 0xbc),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_TS0_TIMER, 0x7f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DLL_HIGHDATARATE, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RESETCODE_OFFSET, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_VGA_INITVAL, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RSM_START, 0x01),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_rx_tbl[] = {
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_PCS_TX_RX_CONFIG, 0x50),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_MAIN_V0_M3P5DB, 0x19),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_POST_V0_M3P5DB, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_MAIN_V0_M6DB, 0x17),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_POST_V0_M6DB, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG5, 0x9f),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_rbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x6f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr2[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr3[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRANSCEIVER_BIAS_EN, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_VMODE_CTRL1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_INTERFACE_SELECT, 0x3d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_CLKBUF_ENABLE, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RESET_TSYNC_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRAN_DRVR_EMP_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_BAND, 0x4),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_POL_INV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_DRV_LVL, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_EMP_POST1_LVL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb5),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4c),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x64),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_RX_PWM_GEAR_BAND, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_DRV_LVL, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
++      QMP_PHY_INIT_CFG(QPHY_RX_SYM_RESYNC_CTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
++      QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_CTRL2, 0x6e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SYM_RESYNC_CTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_CTRL1, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_MIN_HIBERN8_TIME, 0x9a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_INITVAL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x43),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x8a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
++
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x94),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_pcs_tbl[] = {
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x95),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xef),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x60),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x60),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x40, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x54, 2),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0xff, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f, 2),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff, 2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x97),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORE_CLK_EN, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_rbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x6f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr2[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr3[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_VMODE_CTRL1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_INTERFACE_SELECT, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_CLKBUF_ENABLE, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RESET_TSYNC_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_BAND, 0x4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_POL_INV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_DRV_LVL, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_EMP_POST1_LVL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x5),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x6e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x6e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x39),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x39),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x01),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x35),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x30),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x12),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE, 0x33),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x05),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG2, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x08),
++};
++
++static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x26),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x048),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x46),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_CFG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x50),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MISC1, 0x88),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTERNAL_DIG_CORECLK_DIV, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MODE, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_DC_LEVEL_CTRL, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x56),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x22),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_3, 0x13),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_VMODE_CTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_PI_QEC_CTRL, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_FO_GAIN_RATE2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_UCDR_PI_CONTROLS, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_AUX_DATA_TCOARSE_TFINE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_3, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_VGA_CAL_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B1, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B2, 0x5a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B4, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B0, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B1, 0xf9),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B3, 0xce),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B4, 0x62),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B0, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B1, 0x7d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B3, 0xcf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B4, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_PHPRE_CTRL, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_MARG_COARSE_CTRL2, 0x12),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG2, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG4, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG5, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_EQ_CONFIG1, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G3_RXEQEVAL_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_RXEQEVAL_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG2, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_SW_CTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_MX_CTRL2, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdx65_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0b),
++};
++
++static const struct qmp_phy_init_tbl sdx65_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_ENABLES, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_PLL_CNTL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_RX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x35),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_5, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xbb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbb),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3d, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3c, 2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xd2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x13),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_ENABLES, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_INITVAL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x01),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x04),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xd8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_TX_ADAPT_POST_THRESH, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RATE_SLEW_CNTRL1, 0x0b),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG2, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x97),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x46),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_CFG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0xd0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MISC1, 0x88),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORE_CLK_EN, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MODE, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_DC_LEVEL_CTRL, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_PI_CONTROLS, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B1, 0xcc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B3, 0xcc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B5, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B6, 0x29),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B0, 0xc5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B1, 0xad),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B2, 0xb6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B3, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B4, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B5, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B6, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B0, 0xc7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B1, 0xef),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B3, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B4, 0x81),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B5, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B6, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_PHPRE_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_0_1, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_2_3, 0x37),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_3, 0x05),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE3, 0x1f),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE210, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE210, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE210, 0x1f),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE3, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_VGA_CAL_MAN_VAL, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_IDAC_SAOFFSET, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_DAC_ENABLE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_GM_CAL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH2, 0x1f),
++};
++
++/* Register names should be validated, they might be different for this PHY */
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG2, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG3, 0x22),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_G3S2_PRE_GAIN, 0x2e),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x99),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_EQ_CONFIG1, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_RX_MARGINING_CONFIG3, 0x28),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_PRE_GAIN, 0x2e),
++};
++
++struct qmp_phy;
++
++/* struct qmp_phy_cfg - per-PHY initialization config */
++struct qmp_phy_cfg {
++      /* phy-type - PCIE/UFS/USB */
++      unsigned int type;
++      /* number of lanes provided by phy */
++      int nlanes;
++
++      /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
++      const struct qmp_phy_init_tbl *serdes_tbl;
++      int serdes_tbl_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_sec;
++      int serdes_tbl_num_sec;
++      const struct qmp_phy_init_tbl *tx_tbl;
++      int tx_tbl_num;
++      const struct qmp_phy_init_tbl *tx_tbl_sec;
++      int tx_tbl_num_sec;
++      const struct qmp_phy_init_tbl *rx_tbl;
++      int rx_tbl_num;
++      const struct qmp_phy_init_tbl *rx_tbl_sec;
++      int rx_tbl_num_sec;
++      const struct qmp_phy_init_tbl *pcs_tbl;
++      int pcs_tbl_num;
++      const struct qmp_phy_init_tbl *pcs_tbl_sec;
++      int pcs_tbl_num_sec;
++      const struct qmp_phy_init_tbl *pcs_misc_tbl;
++      int pcs_misc_tbl_num;
++      const struct qmp_phy_init_tbl *pcs_misc_tbl_sec;
++      int pcs_misc_tbl_num_sec;
++
++      /* Init sequence for DP PHY block link rates */
++      const struct qmp_phy_init_tbl *serdes_tbl_rbr;
++      int serdes_tbl_rbr_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr;
++      int serdes_tbl_hbr_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr2;
++      int serdes_tbl_hbr2_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr3;
++      int serdes_tbl_hbr3_num;
++
++      /* DP PHY callbacks */
++      int (*configure_dp_phy)(struct qmp_phy *qphy);
++      void (*configure_dp_tx)(struct qmp_phy *qphy);
++      int (*calibrate_dp_phy)(struct qmp_phy *qphy);
++      void (*dp_aux_init)(struct qmp_phy *qphy);
++
++      /* clock ids to be requested */
++      const char * const *clk_list;
++      int num_clks;
++      /* resets to be requested */
++      const char * const *reset_list;
++      int num_resets;
++      /* regulators to be requested */
++      const char * const *vreg_list;
++      int num_vregs;
++
++      /* array of registers with different offsets */
++      const unsigned int *regs;
++
++      unsigned int start_ctrl;
++      unsigned int pwrdn_ctrl;
++      unsigned int mask_com_pcs_ready;
++      /* bit offset of PHYSTATUS in QPHY_PCS_STATUS register */
++      unsigned int phy_status;
++
++      /* true, if PHY has a separate PHY_COM control block */
++      bool has_phy_com_ctrl;
++      /* true, if PHY has a reset for individual lanes */
++      bool has_lane_rst;
++      /* true, if PHY needs delay after POWER_DOWN */
++      bool has_pwrdn_delay;
++      /* power_down delay in usec */
++      int pwrdn_delay_min;
++      int pwrdn_delay_max;
++
++      /* true, if PHY has a separate DP_COM control block */
++      bool has_phy_dp_com_ctrl;
++      /* true, if PHY has secondary tx/rx lanes to be configured */
++      bool is_dual_lane_phy;
++
++      /* true, if PCS block has no separate SW_RESET register */
++      bool no_pcs_sw_reset;
++};
++
++struct qmp_phy_combo_cfg {
++      const struct qmp_phy_cfg *usb_cfg;
++      const struct qmp_phy_cfg *dp_cfg;
++};
++
++/**
++ * struct qmp_phy - per-lane phy descriptor
++ *
++ * @phy: generic phy
++ * @cfg: phy specific configuration
++ * @serdes: iomapped memory space for phy's serdes (i.e. PLL)
++ * @tx: iomapped memory space for lane's tx
++ * @rx: iomapped memory space for lane's rx
++ * @pcs: iomapped memory space for lane's pcs
++ * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
++ * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
++ * @pcs_misc: iomapped memory space for lane's pcs_misc
++ * @pipe_clk: pipe clock
++ * @index: lane index
++ * @qmp: QMP phy to which this lane belongs
++ * @lane_rst: lane's reset controller
++ * @mode: current PHY mode
++ * @dp_aux_cfg: Display port aux config
++ * @dp_opts: Display port optional config
++ * @dp_clks: Display port clocks
++ */
++struct qmp_phy {
++      struct phy *phy;
++      const struct qmp_phy_cfg *cfg;
++      void __iomem *serdes;
++      void __iomem *tx;
++      void __iomem *rx;
++      void __iomem *pcs;
++      void __iomem *tx2;
++      void __iomem *rx2;
++      void __iomem *pcs_misc;
++      struct clk *pipe_clk;
++      unsigned int index;
++      struct qcom_qmp *qmp;
++      struct reset_control *lane_rst;
++      enum phy_mode mode;
++      unsigned int dp_aux_cfg;
++      struct phy_configure_opts_dp dp_opts;
++      struct qmp_phy_dp_clks *dp_clks;
++};
++
++struct qmp_phy_dp_clks {
++      struct qmp_phy *qphy;
++      struct clk_hw dp_link_hw;
++      struct clk_hw dp_pixel_hw;
++};
++
++/**
++ * struct qcom_qmp - structure holding QMP phy block attributes
++ *
++ * @dev: device
++ * @dp_com: iomapped memory space for phy's dp_com control block
++ *
++ * @clks: array of clocks required by phy
++ * @resets: array of resets required by phy
++ * @vregs: regulator supplies bulk data
++ *
++ * @phys: array of per-lane phy descriptors
++ * @phy_mutex: mutex lock for PHY common block initialization
++ * @init_count: phy common block initialization count
++ * @ufs_reset: optional UFS PHY reset handle
++ */
++struct qcom_qmp {
++      struct device *dev;
++      void __iomem *dp_com;
++
++      struct clk_bulk_data *clks;
++      struct reset_control **resets;
++      struct regulator_bulk_data *vregs;
++
++      struct qmp_phy **phys;
++
++      struct mutex phy_mutex;
++      int init_count;
++
++      struct reset_control *ufs_reset;
++};
++
++static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy);
++static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy);
++static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy);
++static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy);
++
++static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy);
++static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy);
++static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy);
++static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy);
++
++static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
++{
++      u32 reg;
++
++      reg = readl(base + offset);
++      reg |= val;
++      writel(reg, base + offset);
++
++      /* ensure that above write is through */
++      readl(base + offset);
++}
++
++static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
++{
++      u32 reg;
++
++      reg = readl(base + offset);
++      reg &= ~val;
++      writel(reg, base + offset);
++
++      /* ensure that above write is through */
++      readl(base + offset);
++}
++
++/* list of clocks required by phy */
++static const char * const msm8996_phy_clk_l[] = {
++      "aux", "cfg_ahb", "ref",
++};
++
++static const char * const msm8996_ufs_phy_clk_l[] = {
++      "ref",
++};
++
++static const char * const qmp_v3_phy_clk_l[] = {
++      "aux", "cfg_ahb", "ref", "com_aux",
++};
++
++static const char * const sdm845_pciephy_clk_l[] = {
++      "aux", "cfg_ahb", "ref", "refgen",
++};
++
++static const char * const qmp_v4_phy_clk_l[] = {
++      "aux", "ref_clk_src", "ref", "com_aux",
++};
++
++/* the primary usb3 phy on sm8250 doesn't have a ref clock */
++static const char * const qmp_v4_sm8250_usbphy_clk_l[] = {
++      "aux", "ref_clk_src", "com_aux"
++};
++
++static const char * const sm8450_ufs_phy_clk_l[] = {
++      "qref", "ref", "ref_aux",
++};
++
++static const char * const sdm845_ufs_phy_clk_l[] = {
++      "ref", "ref_aux",
++};
++
++/* usb3 phy on sdx55 doesn't have com_aux clock */
++static const char * const qmp_v4_sdx55_usbphy_clk_l[] = {
++      "aux", "cfg_ahb", "ref"
++};
++
++static const char * const qcm2290_usb3phy_clk_l[] = {
++      "cfg_ahb", "ref", "com_aux",
++};
++
++/* list of resets */
++static const char * const msm8996_pciephy_reset_l[] = {
++      "phy", "common", "cfg",
++};
++
++static const char * const msm8996_usb3phy_reset_l[] = {
++      "phy", "common",
++};
++
++static const char * const sc7180_usb3phy_reset_l[] = {
++      "phy",
++};
++
++static const char * const qcm2290_usb3phy_reset_l[] = {
++      "phy_phy", "phy",
++};
++
++static const char * const sdm845_pciephy_reset_l[] = {
++      "phy",
++};
++
++/* list of regulators */
++static const char * const qmp_phy_vreg_l[] = {
++      "vdda-phy", "vdda-pll",
++};
++
++static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq8074_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq8074_usb3_serdes_tbl),
++      .tx_tbl                 = msm8996_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_usb3_tx_tbl),
++      .rx_tbl                 = ipq8074_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq8074_usb3_rx_tbl),
++      .pcs_tbl                = ipq8074_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq8074_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++};
++
++static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 3,
++
++      .serdes_tbl             = msm8996_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_pcie_serdes_tbl),
++      .tx_tbl                 = msm8996_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_pcie_tx_tbl),
++      .rx_tbl                 = msm8996_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_pcie_rx_tbl),
++      .pcs_tbl                = msm8996_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8996_pcie_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | PLL_READY_GATE_EN,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .mask_com_pcs_ready     = PCS_READY,
++      .phy_status             = PHYSTATUS,
++
++      .has_phy_com_ctrl       = true,
++      .has_lane_rst           = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg msm8996_ufs_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8996_ufs_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_ufs_serdes_tbl),
++      .tx_tbl                 = msm8996_ufs_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_ufs_tx_tbl),
++      .rx_tbl                 = msm8996_ufs_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_ufs_rx_tbl),
++
++      .clk_list               = msm8996_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_ufs_phy_clk_l),
++
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++
++      .regs                   = msm8996_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8996_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_usb3_serdes_tbl),
++      .tx_tbl                 = msm8996_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_usb3_tx_tbl),
++      .rx_tbl                 = msm8996_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_usb3_rx_tbl),
++      .pcs_tbl                = msm8996_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8996_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++};
++
++static const char * const ipq8074_pciephy_clk_l[] = {
++      "aux", "cfg_ahb",
++};
++/* list of resets */
++static const char * const ipq8074_pciephy_reset_l[] = {
++      "phy", "common",
++};
++
++static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq8074_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq8074_pcie_serdes_tbl),
++      .tx_tbl                 = ipq8074_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_tx_tbl),
++      .rx_tbl                 = ipq8074_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_rx_tbl),
++      .pcs_tbl                = ipq8074_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq8074_pcie_pcs_tbl),
++      .clk_list               = ipq8074_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(ipq8074_pciephy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = NULL,
++      .num_vregs              = 0,
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_phy_com_ctrl       = false,
++      .has_lane_rst           = false,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq6018_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq6018_pcie_serdes_tbl),
++      .tx_tbl                 = ipq6018_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(ipq6018_pcie_tx_tbl),
++      .rx_tbl                 = ipq6018_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq6018_pcie_rx_tbl),
++      .pcs_tbl                = ipq6018_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq6018_pcie_pcs_tbl),
++      .clk_list               = ipq8074_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(ipq8074_pciephy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = NULL,
++      .num_vregs              = 0,
++      .regs                   = ipq_pciephy_gen3_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++
++      .has_phy_com_ctrl       = false,
++      .has_lane_rst           = false,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sdm845_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sdm845_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sdm845_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sdm845_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sdm845_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sdm845_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_qmp_pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdm845_qhp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sdm845_qhp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_qhp_pcie_serdes_tbl),
++      .tx_tbl                 = sdm845_qhp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_qhp_pcie_tx_tbl),
++      .rx_tbl                 = sdm845_qhp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_qhp_pcie_rx_tbl),
++      .pcs_tbl                = sdm845_qhp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_qhp_pcie_pcs_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_qhp_pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sm8250_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
++      .serdes_tbl_sec         = sm8250_qmp_gen3x1_pcie_serdes_tbl,
++      .serdes_tbl_num_sec     = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_serdes_tbl),
++      .tx_tbl                 = sm8250_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sm8250_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
++      .rx_tbl_sec             = sm8250_qmp_gen3x1_pcie_rx_tbl,
++      .rx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_rx_tbl),
++      .pcs_tbl                = sm8250_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
++      .pcs_tbl_sec            = sm8250_qmp_gen3x1_pcie_pcs_tbl,
++      .pcs_tbl_num_sec                = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8250_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
++      .pcs_misc_tbl_sec               = sm8250_qmp_gen3x1_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num_sec   = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sm8250_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sm8250_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
++      .tx_tbl_sec             = sm8250_qmp_gen3x2_pcie_tx_tbl,
++      .tx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_tx_tbl),
++      .rx_tbl                 = sm8250_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
++      .rx_tbl_sec             = sm8250_qmp_gen3x2_pcie_rx_tbl,
++      .rx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_rx_tbl),
++      .pcs_tbl                = sm8250_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
++      .pcs_tbl_sec            = sm8250_qmp_gen3x2_pcie_pcs_tbl,
++      .pcs_tbl_num_sec                = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8250_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
++      .pcs_misc_tbl_sec               = sm8250_qmp_gen3x2_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num_sec   = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc7180_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v3_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v3_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v3_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v3_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v3_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v3_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v3_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v3_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v3_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sc7180_usb3dpphy_cfg = {
++      .usb_cfg                = &sc7180_usb3phy_cfg,
++      .dp_cfg                 = &sc7180_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sdm845_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
++      .tx_tbl                 = sdm845_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
++      .rx_tbl                 = sdm845_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
++      .pcs_tbl                = sdm845_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm6115_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm6115_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
++      .rx_tbl                 = sm6115_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
++      .pcs_tbl                = sm6115_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm6115_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++
++      .is_dual_lane_phy       = false,
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8998_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8998_pcie_serdes_tbl),
++      .tx_tbl                 = msm8998_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8998_pcie_tx_tbl),
++      .rx_tbl                 = msm8998_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8998_pcie_rx_tbl),
++      .pcs_tbl                = msm8998_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8998_pcie_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++};
++
++static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8998_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl),
++      .tx_tbl                 = msm8998_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8998_usb3_tx_tbl),
++      .rx_tbl                 = msm8998_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
++      .pcs_tbl                = msm8998_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8150_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8150_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8150_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8150_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8150_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_usb3_tx_tbl),
++      .rx_tbl                 = sm8150_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_usb3_rx_tbl),
++      .pcs_tbl                = sm8150_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sc8180x_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sc8180x_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sc8180x_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sc8180x_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sc8180x_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sc8180x_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sc8180x_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v4_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v4_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v4_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v4_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v4_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v4_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sc8180x_usb3dpphy_cfg = {
++      .usb_cfg                = &sm8150_usb3phy_cfg,
++      .dp_cfg                 = &sc8180x_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8150_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8150_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8150_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8250_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_usb3_tx_tbl),
++      .rx_tbl                 = sm8250_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_usb3_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_sm8250_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8250_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8250_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8250_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v4_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v4_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v4_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v4_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v4_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v4_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sm8250_usb3dpphy_cfg = {
++      .usb_cfg                = &sm8250_usb3phy_cfg,
++      .dp_cfg                 = &sm8250_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sdx55_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx55_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sdx55_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx55_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_sdx55_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sdx55_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdx55_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sdx55_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx55_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sdx55_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx55_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sdx55_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdx55_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sdx55_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sdx55_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS_4_20,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sdx65_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx65_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sdx65_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx65_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_sdx55_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8350_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8350_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8350_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8350_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8350_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8350_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_usb3_tx_tbl),
++      .rx_tbl                 = sm8350_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_usb3_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_sm8250_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8350_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8350_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8350_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8350_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8350_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8350_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8350_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
++      .clk_list               = sm8450_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sm8450_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8450_qmp_gen3x1_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sm8450_qmp_gen3x1_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_serdes_tbl),
++      .tx_tbl                 = sm8450_qmp_gen3x1_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_tx_tbl),
++      .rx_tbl                 = sm8450_qmp_gen3x1_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_rx_tbl),
++      .pcs_tbl                = sm8450_qmp_gen3x1_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8450_qmp_gen3x1_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8450_qmp_gen4x2_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sm8450_qmp_gen4x2_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_serdes_tbl),
++      .tx_tbl                 = sm8450_qmp_gen4x2_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_tx_tbl),
++      .rx_tbl                 = sm8450_qmp_gen4x2_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_rx_tbl),
++      .pcs_tbl                = sm8450_qmp_gen4x2_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8450_qmp_gen4x2_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS_4_20,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qcm2290_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
++      .tx_tbl                 = qcm2290_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_tx_tbl),
++      .rx_tbl                 = qcm2290_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_rx_tbl),
++      .pcs_tbl                = qcm2290_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
++      .clk_list               = qcm2290_usb3phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qcm2290_usb3phy_clk_l),
++      .reset_list             = qcm2290_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(qcm2290_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qcm2290_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static void qcom_qmp_phy_configure_lane(void __iomem *base,
++                                      const unsigned int *regs,
++                                      const struct qmp_phy_init_tbl tbl[],
++                                      int num,
++                                      u8 lane_mask)
++{
++      int i;
++      const struct qmp_phy_init_tbl *t = tbl;
++
++      if (!t)
++              return;
++
++      for (i = 0; i < num; i++, t++) {
++              if (!(t->lane_mask & lane_mask))
++                      continue;
++
++              if (t->in_layout)
++                      writel(t->val, base + regs[t->offset]);
++              else
++                      writel(t->val, base + t->offset);
++      }
++}
++
++static void qcom_qmp_phy_configure(void __iomem *base,
++                                 const unsigned int *regs,
++                                 const struct qmp_phy_init_tbl tbl[],
++                                 int num)
++{
++      qcom_qmp_phy_configure_lane(base, regs, tbl, num, 0xff);
++}
++
++static int qcom_qmp_phy_serdes_init(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
++      int serdes_tbl_num = cfg->serdes_tbl_num;
++      int ret;
++
++      qcom_qmp_phy_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num);
++      if (cfg->serdes_tbl_sec)
++              qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl_sec,
++                                     cfg->serdes_tbl_num_sec);
++
++      if (cfg->type == PHY_TYPE_DP) {
++              switch (dp_opts->link_rate) {
++              case 1620:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_rbr,
++                                             cfg->serdes_tbl_rbr_num);
++                      break;
++              case 2700:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr,
++                                             cfg->serdes_tbl_hbr_num);
++                      break;
++              case 5400:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr2,
++                                             cfg->serdes_tbl_hbr2_num);
++                      break;
++              case 8100:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr3,
++                                             cfg->serdes_tbl_hbr3_num);
++                      break;
++              default:
++                      /* Other link rates aren't supported */
++                      return -EINVAL;
++              }
++      }
++
++
++      if (cfg->has_phy_com_ctrl) {
++              void __iomem *status;
++              unsigned int mask, val;
++
++              qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET], SW_RESET);
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
++                           SERDES_START | PCS_START);
++
++              status = serdes + cfg->regs[QPHY_COM_PCS_READY_STATUS];
++              mask = cfg->mask_com_pcs_ready;
++
++              ret = readl_poll_timeout(status, val, (val & mask), 10,
++                                       PHY_INIT_COMPLETE_TIMEOUT);
++              if (ret) {
++                      dev_err(qmp->dev,
++                              "phy common block init timed-out\n");
++                      return ret;
++              }
++      }
++
++      return 0;
++}
++
++static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy)
++{
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      /* Turn on BIAS current for PHY/PLL */
++      writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX |
++             QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL,
++             qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_LANE_0_1_PWRDN |
++             DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN |
++             DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(QSERDES_V3_COM_BIAS_EN |
++             QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN |
++             QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL |
++             QSERDES_V3_COM_CLKBUF_RX_DRIVE_L,
++             qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0x24, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
++      writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
++      writel(0xbb, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
++      qphy->dp_aux_cfg = 0;
++
++      writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
++             PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
++             PHY_AUX_REQ_ERR_MASK,
++             qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
++}
++
++static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = {
++      { 0x00, 0x0c, 0x15, 0x1a },
++      { 0x02, 0x0e, 0x16, 0xff },
++      { 0x02, 0x11, 0xff, 0xff },
++      { 0x04, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_voltage_swing_hbr3_hbr2[4][4] = {
++      { 0x02, 0x12, 0x16, 0x1a },
++      { 0x09, 0x19, 0x1f, 0xff },
++      { 0x10, 0x1f, 0xff, 0xff },
++      { 0x1f, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = {
++      { 0x00, 0x0c, 0x14, 0x19 },
++      { 0x00, 0x0b, 0x12, 0xff },
++      { 0x00, 0x0b, 0xff, 0xff },
++      { 0x04, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
++      { 0x08, 0x0f, 0x16, 0x1f },
++      { 0x11, 0x1e, 0x1f, 0xff },
++      { 0x19, 0x1f, 0xff, 0xff },
++      { 0x1f, 0xff, 0xff, 0xff }
++};
++
++static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy,
++              unsigned int drv_lvl_reg, unsigned int emp_post_reg)
++{
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      unsigned int v_level = 0, p_level = 0;
++      u8 voltage_swing_cfg, pre_emphasis_cfg;
++      int i;
++
++      for (i = 0; i < dp_opts->lanes; i++) {
++              v_level = max(v_level, dp_opts->voltage[i]);
++              p_level = max(p_level, dp_opts->pre[i]);
++      }
++
++      if (dp_opts->link_rate <= 2700) {
++              voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
++              pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
++      } else {
++              voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr3_hbr2[v_level][p_level];
++              pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr3_hbr2[v_level][p_level];
++      }
++
++      /* TODO: Move check to config check */
++      if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
++              return -EINVAL;
++
++      /* Enable MUX to use Cursor values from these registers */
++      voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
++      pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
++
++      writel(voltage_swing_cfg, qphy->tx + drv_lvl_reg);
++      writel(pre_emphasis_cfg, qphy->tx + emp_post_reg);
++      writel(voltage_swing_cfg, qphy->tx2 + drv_lvl_reg);
++      writel(pre_emphasis_cfg, qphy->tx2 + emp_post_reg);
++
++      return 0;
++}
++
++static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)
++{
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 bias_en, drvr_en;
++
++      if (qcom_qmp_phy_configure_dp_swing(qphy,
++                              QSERDES_V3_TX_TX_DRV_LVL,
++                              QSERDES_V3_TX_TX_EMP_POST1_LVL) < 0)
++              return;
++
++      if (dp_opts->lanes == 1) {
++              bias_en = 0x3e;
++              drvr_en = 0x13;
++      } else {
++              bias_en = 0x3f;
++              drvr_en = 0x10;
++      }
++
++      writel(drvr_en, qphy->tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
++      writel(bias_en, qphy->tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
++      writel(drvr_en, qphy->tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
++      writel(bias_en, qphy->tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
++}
++
++static bool qcom_qmp_phy_configure_dp_mode(struct qmp_phy *qphy)
++{
++      u32 val;
++      bool reverse = false;
++
++      val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++            DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN;
++
++      /*
++       * TODO: Assume orientation is CC1 for now and two lanes, need to
++       * use type-c connector to understand orientation and lanes.
++       *
++       * Otherwise val changes to be like below if this code understood
++       * the orientation of the type-c cable.
++       *
++       * if (lane_cnt == 4 || orientation == ORIENTATION_CC2)
++       *      val |= DP_PHY_PD_CTL_LANE_0_1_PWRDN;
++       * if (lane_cnt == 4 || orientation == ORIENTATION_CC1)
++       *      val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
++       * if (orientation == ORIENTATION_CC2)
++       *      writel(0x4c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
++       */
++      val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
++      writel(val, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(0x5c, qphy->pcs + QSERDES_DP_PHY_MODE);
++
++      return reverse;
++}
++
++static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 phy_vco_div, status;
++      unsigned long pixel_freq;
++
++      qcom_qmp_phy_configure_dp_mode(qphy);
++
++      writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
++      writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              phy_vco_div = 0x1;
++              pixel_freq = 1620000000UL / 2;
++              break;
++      case 2700:
++              phy_vco_div = 0x1;
++              pixel_freq = 2700000000UL / 2;
++              break;
++      case 5400:
++              phy_vco_div = 0x2;
++              pixel_freq = 5400000000UL / 4;
++              break;
++      case 8100:
++              phy_vco_div = 0x0;
++              pixel_freq = 8100000000UL / 6;
++              break;
++      default:
++              /* Other link rates aren't supported */
++              return -EINVAL;
++      }
++      writel(phy_vco_div, qphy->pcs + QSERDES_V3_DP_PHY_VCO_DIV);
++
++      clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
++      clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
++
++      writel(0x04, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      writel(0x20, qphy->serdes + QSERDES_V3_COM_RESETSM_CNTRL);
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V3_COM_C_READY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
++      udelay(2000);
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      return readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000);
++}
++
++/*
++ * We need to calibrate the aux setting here as many times
++ * as the caller tries
++ */
++static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy)
++{
++      static const u8 cfg1_settings[] = { 0x13, 0x23, 0x1d };
++      u8 val;
++
++      qphy->dp_aux_cfg++;
++      qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
++      val = cfg1_settings[qphy->dp_aux_cfg];
++
++      writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++
++      return 0;
++}
++
++static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy)
++{
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      /* Turn on BIAS current for PHY/PLL */
++      writel(0x17, qphy->serdes + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
++      writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
++      writel(0xb7, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
++      qphy->dp_aux_cfg = 0;
++
++      writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
++             PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
++             PHY_AUX_REQ_ERR_MASK,
++             qphy->pcs + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
++}
++
++static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy)
++{
++      /* Program default values before writing proper values */
++      writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
++      writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
++
++      writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++      writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++
++      qcom_qmp_phy_configure_dp_swing(qphy,
++                      QSERDES_V4_TX_TX_DRV_LVL,
++                      QSERDES_V4_TX_TX_EMP_POST1_LVL);
++}
++
++static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 phy_vco_div, status;
++      unsigned long pixel_freq;
++      u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
++      bool reverse;
++
++      writel(0x0f, qphy->pcs + QSERDES_V4_DP_PHY_CFG_1);
++
++      reverse = qcom_qmp_phy_configure_dp_mode(qphy);
++
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++
++      writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL);
++      writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL);
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              phy_vco_div = 0x1;
++              pixel_freq = 1620000000UL / 2;
++              break;
++      case 2700:
++              phy_vco_div = 0x1;
++              pixel_freq = 2700000000UL / 2;
++              break;
++      case 5400:
++              phy_vco_div = 0x2;
++              pixel_freq = 5400000000UL / 4;
++              break;
++      case 8100:
++              phy_vco_div = 0x0;
++              pixel_freq = 8100000000UL / 6;
++              break;
++      default:
++              /* Other link rates aren't supported */
++              return -EINVAL;
++      }
++      writel(phy_vco_div, qphy->pcs + QSERDES_V4_DP_PHY_VCO_DIV);
++
++      clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
++      clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
++
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      writel(0x20, qphy->serdes + QSERDES_V4_COM_RESETSM_CNTRL);
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_C_READY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      /*
++       * At least for 7nm DP PHY this has to be done after enabling link
++       * clock.
++       */
++
++      if (dp_opts->lanes == 1) {
++              bias0_en = reverse ? 0x3e : 0x15;
++              bias1_en = reverse ? 0x15 : 0x3e;
++              drvr0_en = reverse ? 0x13 : 0x10;
++              drvr1_en = reverse ? 0x10 : 0x13;
++      } else if (dp_opts->lanes == 2) {
++              bias0_en = reverse ? 0x3f : 0x15;
++              bias1_en = reverse ? 0x15 : 0x3f;
++              drvr0_en = 0x10;
++              drvr1_en = 0x10;
++      } else {
++              bias0_en = 0x3f;
++              bias1_en = 0x3f;
++              drvr0_en = 0x10;
++              drvr1_en = 0x10;
++      }
++
++      writel(drvr0_en, qphy->tx + QSERDES_V4_TX_HIGHZ_DRVR_EN);
++      writel(bias0_en, qphy->tx + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
++      writel(drvr1_en, qphy->tx2 + QSERDES_V4_TX_HIGHZ_DRVR_EN);
++      writel(bias1_en, qphy->tx2 + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
++
++      writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
++      udelay(2000);
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x0a, qphy->tx + QSERDES_V4_TX_TX_POL_INV);
++      writel(0x0a, qphy->tx2 + QSERDES_V4_TX_TX_POL_INV);
++
++      writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
++      writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
++
++      writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++      writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++
++      return 0;
++}
++
++/*
++ * We need to calibrate the aux setting here as many times
++ * as the caller tries
++ */
++static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy)
++{
++      static const u8 cfg1_settings[] = { 0x20, 0x13, 0x23, 0x1d };
++      u8 val;
++
++      qphy->dp_aux_cfg++;
++      qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
++      val = cfg1_settings[qphy->dp_aux_cfg];
++
++      writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++
++      return 0;
++}
++
++static int qcom_qmp_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
++{
++      const struct phy_configure_opts_dp *dp_opts = &opts->dp;
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      memcpy(&qphy->dp_opts, dp_opts, sizeof(*dp_opts));
++      if (qphy->dp_opts.set_voltages) {
++              cfg->configure_dp_tx(qphy);
++              qphy->dp_opts.set_voltages = 0;
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_dp_phy_calibrate(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      if (cfg->calibrate_dp_phy)
++              return cfg->calibrate_dp_phy(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_com_init(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *dp_com = qmp->dp_com;
++      int ret, i;
++
++      mutex_lock(&qmp->phy_mutex);
++      if (qmp->init_count++) {
++              mutex_unlock(&qmp->phy_mutex);
++              return 0;
++      }
++
++      /* turn on regulator supplies */
++      ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
++      if (ret) {
++              dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
++              goto err_unlock;
++      }
++
++      for (i = 0; i < cfg->num_resets; i++) {
++              ret = reset_control_assert(qmp->resets[i]);
++              if (ret) {
++                      dev_err(qmp->dev, "%s reset assert failed\n",
++                              cfg->reset_list[i]);
++                      goto err_disable_regulators;
++              }
++      }
++
++      for (i = cfg->num_resets - 1; i >= 0; i--) {
++              ret = reset_control_deassert(qmp->resets[i]);
++              if (ret) {
++                      dev_err(qmp->dev, "%s reset deassert failed\n",
++                              qphy->cfg->reset_list[i]);
++                      goto err_assert_reset;
++              }
++      }
++
++      ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
++      if (ret)
++              goto err_assert_reset;
++
++      if (cfg->has_phy_dp_com_ctrl) {
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_POWER_DOWN_CTRL,
++                           SW_PWRDN);
++              /* override hardware control for reset of qmp phy */
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
++                           SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
++                           SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
++
++              /* Default type-c orientation, i.e CC1 */
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_TYPEC_CTRL, 0x02);
++
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_PHY_MODE_CTRL,
++                           USB3_MODE | DP_MODE);
++
++              /* bring both QMP USB and QMP DP PHYs PCS block out of reset */
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
++                           SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
++                           SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
++
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_SWI_CTRL, 0x03);
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
++      }
++
++      if (cfg->has_phy_com_ctrl) {
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
++                           SW_PWRDN);
++      } else {
++              if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
++                      qphy_setbits(pcs,
++                                      cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++                                      cfg->pwrdn_ctrl);
++              else
++                      qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL,
++                                      cfg->pwrdn_ctrl);
++      }
++
++      mutex_unlock(&qmp->phy_mutex);
++
++      return 0;
++
++err_assert_reset:
++      while (++i < cfg->num_resets)
++              reset_control_assert(qmp->resets[i]);
++err_disable_regulators:
++      regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
++err_unlock:
++      mutex_unlock(&qmp->phy_mutex);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_com_exit(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      int i = cfg->num_resets;
++
++      mutex_lock(&qmp->phy_mutex);
++      if (--qmp->init_count) {
++              mutex_unlock(&qmp->phy_mutex);
++              return 0;
++      }
++
++      reset_control_assert(qmp->ufs_reset);
++      if (cfg->has_phy_com_ctrl) {
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
++                           SERDES_START | PCS_START);
++              qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET],
++                           SW_RESET);
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
++                           SW_PWRDN);
++      }
++
++      while (--i >= 0)
++              reset_control_assert(qmp->resets[i]);
++
++      clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++
++      regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
++
++      mutex_unlock(&qmp->phy_mutex);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_init(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      int ret;
++      dev_vdbg(qmp->dev, "Initializing QMP phy\n");
++
++      if (cfg->no_pcs_sw_reset) {
++              /*
++               * Get UFS reset, which is delayed until now to avoid a
++               * circular dependency where UFS needs its PHY, but the PHY
++               * needs this UFS reset.
++               */
++              if (!qmp->ufs_reset) {
++                      qmp->ufs_reset =
++                              devm_reset_control_get_exclusive(qmp->dev,
++                                                               "ufsphy");
++
++                      if (IS_ERR(qmp->ufs_reset)) {
++                              ret = PTR_ERR(qmp->ufs_reset);
++                              dev_err(qmp->dev,
++                                      "failed to get UFS reset: %d\n",
++                                      ret);
++
++                              qmp->ufs_reset = NULL;
++                              return ret;
++                      }
++              }
++
++              ret = reset_control_assert(qmp->ufs_reset);
++              if (ret)
++                      return ret;
++      }
++
++      ret = qcom_qmp_phy_com_init(qphy);
++      if (ret)
++              return ret;
++
++      if (cfg->type == PHY_TYPE_DP)
++              cfg->dp_aux_init(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_power_on(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *tx = qphy->tx;
++      void __iomem *rx = qphy->rx;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++      void __iomem *status;
++      unsigned int mask, val, ready;
++      int ret;
++
++      qcom_qmp_phy_serdes_init(qphy);
++
++      if (cfg->has_lane_rst) {
++              ret = reset_control_deassert(qphy->lane_rst);
++              if (ret) {
++                      dev_err(qmp->dev, "lane%d reset deassert failed\n",
++                              qphy->index);
++                      return ret;
++              }
++      }
++
++      ret = clk_prepare_enable(qphy->pipe_clk);
++      if (ret) {
++              dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
++              goto err_reset_lane;
++      }
++
++      /* Tx, Rx, and PCS configurations */
++      qcom_qmp_phy_configure_lane(tx, cfg->regs,
++                                  cfg->tx_tbl, cfg->tx_tbl_num, 1);
++      if (cfg->tx_tbl_sec)
++              qcom_qmp_phy_configure_lane(tx, cfg->regs, cfg->tx_tbl_sec,
++                                          cfg->tx_tbl_num_sec, 1);
++
++      /* Configuration for other LANE for USB-DP combo PHY */
++      if (cfg->is_dual_lane_phy) {
++              qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
++                                          cfg->tx_tbl, cfg->tx_tbl_num, 2);
++              if (cfg->tx_tbl_sec)
++                      qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
++                                                  cfg->tx_tbl_sec,
++                                                  cfg->tx_tbl_num_sec, 2);
++      }
++
++      /* Configure special DP tx tunings */
++      if (cfg->type == PHY_TYPE_DP)
++              cfg->configure_dp_tx(qphy);
++
++      qcom_qmp_phy_configure_lane(rx, cfg->regs,
++                                  cfg->rx_tbl, cfg->rx_tbl_num, 1);
++      if (cfg->rx_tbl_sec)
++              qcom_qmp_phy_configure_lane(rx, cfg->regs,
++                                          cfg->rx_tbl_sec, cfg->rx_tbl_num_sec, 1);
++
++      if (cfg->is_dual_lane_phy) {
++              qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
++                                          cfg->rx_tbl, cfg->rx_tbl_num, 2);
++              if (cfg->rx_tbl_sec)
++                      qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
++                                                  cfg->rx_tbl_sec,
++                                                  cfg->rx_tbl_num_sec, 2);
++      }
++
++      /* Configure link rate, swing, etc. */
++      if (cfg->type == PHY_TYPE_DP) {
++              cfg->configure_dp_phy(qphy);
++      } else {
++              qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
++              if (cfg->pcs_tbl_sec)
++                      qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl_sec,
++                                             cfg->pcs_tbl_num_sec);
++      }
++
++      ret = reset_control_deassert(qmp->ufs_reset);
++      if (ret)
++              goto err_disable_pipe_clk;
++
++      qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl,
++                             cfg->pcs_misc_tbl_num);
++      if (cfg->pcs_misc_tbl_sec)
++              qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl_sec,
++                                     cfg->pcs_misc_tbl_num_sec);
++
++      /*
++       * Pull out PHY from POWER DOWN state.
++       * This is active low enable signal to power-down PHY.
++       */
++      if(cfg->type == PHY_TYPE_PCIE)
++              qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
++
++      if (cfg->has_pwrdn_delay)
++              usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
++
++      if (cfg->type != PHY_TYPE_DP) {
++              /* Pull PHY out of reset state */
++              if (!cfg->no_pcs_sw_reset)
++                      qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
++              /* start SerDes and Phy-Coding-Sublayer */
++              qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
++
++              if (cfg->type == PHY_TYPE_UFS) {
++                      status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
++                      mask = PCS_READY;
++                      ready = PCS_READY;
++              } else {
++                      status = pcs + cfg->regs[QPHY_PCS_STATUS];
++                      mask = cfg->phy_status;
++                      ready = 0;
++              }
++
++              ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
++                                       PHY_INIT_COMPLETE_TIMEOUT);
++              if (ret) {
++                      dev_err(qmp->dev, "phy initialization timed-out\n");
++                      goto err_disable_pipe_clk;
++              }
++      }
++      return 0;
++
++err_disable_pipe_clk:
++      clk_disable_unprepare(qphy->pipe_clk);
++err_reset_lane:
++      if (cfg->has_lane_rst)
++              reset_control_assert(qphy->lane_rst);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_power_off(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      clk_disable_unprepare(qphy->pipe_clk);
++
++      if (cfg->type == PHY_TYPE_DP) {
++              /* Assert DP PHY power down */
++              writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++      } else {
++              /* PHY reset */
++              if (!cfg->no_pcs_sw_reset)
++                      qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
++
++              /* stop SerDes and Phy-Coding-Sublayer */
++              qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
++
++              /* Put PHY into POWER DOWN state: active low */
++              if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) {
++                      qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++                                   cfg->pwrdn_ctrl);
++              } else {
++                      qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL,
++                                      cfg->pwrdn_ctrl);
++              }
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_phy_exit(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      if (cfg->has_lane_rst)
++              reset_control_assert(qphy->lane_rst);
++
++      qcom_qmp_phy_com_exit(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_enable(struct phy *phy)
++{
++      int ret;
++
++      ret = qcom_qmp_phy_init(phy);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_power_on(phy);
++      if (ret)
++              qcom_qmp_phy_exit(phy);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_disable(struct phy *phy)
++{
++      int ret;
++
++      ret = qcom_qmp_phy_power_off(phy);
++      if (ret)
++              return ret;
++      return qcom_qmp_phy_exit(phy);
++}
++
++static int qcom_qmp_phy_set_mode(struct phy *phy,
++                               enum phy_mode mode, int submode)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++
++      qphy->mode = mode;
++
++      return 0;
++}
++
++static void qcom_qmp_phy_enable_autonomous_mode(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++      u32 intr_mask;
++
++      if (qphy->mode == PHY_MODE_USB_HOST_SS ||
++          qphy->mode == PHY_MODE_USB_DEVICE_SS)
++              intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
++      else
++              intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
++
++      /* Clear any pending interrupts status */
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++      /* Writing 1 followed by 0 clears the interrupt */
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
++                   ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);
++
++      /* Enable required PHY autonomous mode interrupts */
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
++
++      /* Enable i/o clamp_n for autonomous mode */
++      if (pcs_misc)
++              qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
++}
++
++static void qcom_qmp_phy_disable_autonomous_mode(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++
++      /* Disable i/o clamp_n on resume for normal mode */
++      if (pcs_misc)
++              qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
++
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
++                   ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
++
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++      /* Writing 1 followed by 0 clears the interrupt */
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++}
++
++static int __maybe_unused qcom_qmp_phy_runtime_suspend(struct device *dev)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct qmp_phy *qphy = qmp->phys[0];
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qphy->mode);
++
++      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
++      if (cfg->type != PHY_TYPE_USB3)
++              return 0;
++
++      if (!qmp->init_count) {
++              dev_vdbg(dev, "PHY not initialized, bailing out\n");
++              return 0;
++      }
++
++      qcom_qmp_phy_enable_autonomous_mode(qphy);
++
++      clk_disable_unprepare(qphy->pipe_clk);
++      clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++
++      return 0;
++}
++
++static int __maybe_unused qcom_qmp_phy_runtime_resume(struct device *dev)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct qmp_phy *qphy = qmp->phys[0];
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      int ret = 0;
++
++      dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qphy->mode);
++
++      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
++      if (cfg->type != PHY_TYPE_USB3)
++              return 0;
++
++      if (!qmp->init_count) {
++              dev_vdbg(dev, "PHY not initialized, bailing out\n");
++              return 0;
++      }
++
++      ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
++      if (ret)
++              return ret;
++
++      ret = clk_prepare_enable(qphy->pipe_clk);
++      if (ret) {
++              dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
++              clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++              return ret;
++      }
++
++      qcom_qmp_phy_disable_autonomous_mode(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int num = cfg->num_vregs;
++      int i;
++
++      qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
++      if (!qmp->vregs)
++              return -ENOMEM;
++
++      for (i = 0; i < num; i++)
++              qmp->vregs[i].supply = cfg->vreg_list[i];
++
++      return devm_regulator_bulk_get(dev, num, qmp->vregs);
++}
++
++static int qcom_qmp_phy_reset_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int i;
++
++      qmp->resets = devm_kcalloc(dev, cfg->num_resets,
++                                 sizeof(*qmp->resets), GFP_KERNEL);
++      if (!qmp->resets)
++              return -ENOMEM;
++
++      for (i = 0; i < cfg->num_resets; i++) {
++              struct reset_control *rst;
++              const char *name = cfg->reset_list[i];
++
++              rst = devm_reset_control_get_exclusive(dev, name);
++              if (IS_ERR(rst)) {
++                      dev_err(dev, "failed to get %s reset\n", name);
++                      return PTR_ERR(rst);
++              }
++              qmp->resets[i] = rst;
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_phy_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int num = cfg->num_clks;
++      int i;
++
++      qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
++      if (!qmp->clks)
++              return -ENOMEM;
++
++      for (i = 0; i < num; i++)
++              qmp->clks[i].id = cfg->clk_list[i];
++
++      return devm_clk_bulk_get(dev, num, qmp->clks);
++}
++
++static void phy_clk_release_provider(void *res)
++{
++      of_clk_del_provider(res);
++}
++
++/*
++ * Register a fixed rate pipe clock.
++ *
++ * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
++ * controls it. The <s>_pipe_clk coming out of the GCC is requested
++ * by the PHY driver for its operations.
++ * We register the <s>_pipe_clksrc here. The gcc driver takes care
++ * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
++ * Below picture shows this relationship.
++ *
++ *         +---------------+
++ *         |   PHY block   |<<---------------------------------------+
++ *         |               |                                         |
++ *         |   +-------+   |                   +-----+               |
++ *   I/P---^-->|  PLL  |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
++ *    clk  |   +-------+   |                   +-----+
++ *         +---------------+
++ */
++static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
++{
++      struct clk_fixed_rate *fixed;
++      struct clk_init_data init = { };
++      int ret;
++
++      ret = of_property_read_string(np, "clock-output-names", &init.name);
++      if (ret) {
++              dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
++              return ret;
++      }
++
++      fixed = devm_kzalloc(qmp->dev, sizeof(*fixed), GFP_KERNEL);
++      if (!fixed)
++              return -ENOMEM;
++
++      init.ops = &clk_fixed_rate_ops;
++
++      /* controllers using QMP phys use 125MHz pipe clock interface */
++      fixed->fixed_rate = 125000000;
++      fixed->hw.init = &init;
++
++      ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
++      if (ret)
++              return ret;
++
++      ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
++      if (ret)
++              return ret;
++
++      /*
++       * Roll a devm action because the clock provider is the child node, but
++       * the child node is not actually a device.
++       */
++      return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
++}
++
++/*
++ * Display Port PLL driver block diagram for branch clocks
++ *
++ *              +------------------------------+
++ *              |         DP_VCO_CLK           |
++ *              |                              |
++ *              |    +-------------------+     |
++ *              |    |   (DP PLL/VCO)    |     |
++ *              |    +---------+---------+     |
++ *              |              v               |
++ *              |   +----------+-----------+   |
++ *              |   | hsclk_divsel_clk_src |   |
++ *              |   +----------+-----------+   |
++ *              +------------------------------+
++ *                              |
++ *          +---------<---------v------------>----------+
++ *          |                                           |
++ * +--------v----------------+                          |
++ * |    dp_phy_pll_link_clk  |                          |
++ * |     link_clk            |                          |
++ * +--------+----------------+                          |
++ *          |                                           |
++ *          |                                           |
++ *          v                                           v
++ * Input to DISPCC block                                |
++ * for link clk, crypto clk                             |
++ * and interface clock                                  |
++ *                                                      |
++ *                                                      |
++ *      +--------<------------+-----------------+---<---+
++ *      |                     |                 |
++ * +----v---------+  +--------v-----+  +--------v------+
++ * | vco_divided  |  | vco_divided  |  | vco_divided   |
++ * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
++ * |              |  |              |  |               |
++ * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
++ * +-------+------+  +-----+--------+  +--------+------+
++ *         |                 |                  |
++ *         v---->----------v-------------<------v
++ *                         |
++ *              +----------+-----------------+
++ *              |   dp_phy_pll_vco_div_clk   |
++ *              +---------+------------------+
++ *                        |
++ *                        v
++ *              Input to DISPCC block
++ *              for DP pixel clock
++ *
++ */
++static int qcom_qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
++                                              struct clk_rate_request *req)
++{
++      switch (req->rate) {
++      case 1620000000UL / 2:
++      case 2700000000UL / 2:
++      /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
++              return 0;
++      default:
++              return -EINVAL;
++      }
++}
++
++static unsigned long
++qcom_qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
++{
++      const struct qmp_phy_dp_clks *dp_clks;
++      const struct qmp_phy *qphy;
++      const struct phy_configure_opts_dp *dp_opts;
++
++      dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_pixel_hw);
++      qphy = dp_clks->qphy;
++      dp_opts = &qphy->dp_opts;
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              return 1620000000UL / 2;
++      case 2700:
++              return 2700000000UL / 2;
++      case 5400:
++              return 5400000000UL / 4;
++      case 8100:
++              return 8100000000UL / 6;
++      default:
++              return 0;
++      }
++}
++
++static const struct clk_ops qcom_qmp_dp_pixel_clk_ops = {
++      .determine_rate = qcom_qmp_dp_pixel_clk_determine_rate,
++      .recalc_rate = qcom_qmp_dp_pixel_clk_recalc_rate,
++};
++
++static int qcom_qmp_dp_link_clk_determine_rate(struct clk_hw *hw,
++                                             struct clk_rate_request *req)
++{
++      switch (req->rate) {
++      case 162000000:
++      case 270000000:
++      case 540000000:
++      case 810000000:
++              return 0;
++      default:
++              return -EINVAL;
++      }
++}
++
++static unsigned long
++qcom_qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
++{
++      const struct qmp_phy_dp_clks *dp_clks;
++      const struct qmp_phy *qphy;
++      const struct phy_configure_opts_dp *dp_opts;
++
++      dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_link_hw);
++      qphy = dp_clks->qphy;
++      dp_opts = &qphy->dp_opts;
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++      case 2700:
++      case 5400:
++      case 8100:
++              return dp_opts->link_rate * 100000;
++      default:
++              return 0;
++      }
++}
++
++static const struct clk_ops qcom_qmp_dp_link_clk_ops = {
++      .determine_rate = qcom_qmp_dp_link_clk_determine_rate,
++      .recalc_rate = qcom_qmp_dp_link_clk_recalc_rate,
++};
++
++static struct clk_hw *
++qcom_qmp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *data)
++{
++      struct qmp_phy_dp_clks *dp_clks = data;
++      unsigned int idx = clkspec->args[0];
++
++      if (idx >= 2) {
++              pr_err("%s: invalid index %u\n", __func__, idx);
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (idx == 0)
++              return &dp_clks->dp_link_hw;
++
++      return &dp_clks->dp_pixel_hw;
++}
++
++static int phy_dp_clks_register(struct qcom_qmp *qmp, struct qmp_phy *qphy,
++                              struct device_node *np)
++{
++      struct clk_init_data init = { };
++      struct qmp_phy_dp_clks *dp_clks;
++      char name[64];
++      int ret;
++
++      dp_clks = devm_kzalloc(qmp->dev, sizeof(*dp_clks), GFP_KERNEL);
++      if (!dp_clks)
++              return -ENOMEM;
++
++      dp_clks->qphy = qphy;
++      qphy->dp_clks = dp_clks;
++
++      snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
++      init.ops = &qcom_qmp_dp_link_clk_ops;
++      init.name = name;
++      dp_clks->dp_link_hw.init = &init;
++      ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_link_hw);
++      if (ret)
++              return ret;
++
++      snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
++      init.ops = &qcom_qmp_dp_pixel_clk_ops;
++      init.name = name;
++      dp_clks->dp_pixel_hw.init = &init;
++      ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_pixel_hw);
++      if (ret)
++              return ret;
++
++      ret = of_clk_add_hw_provider(np, qcom_qmp_dp_clks_hw_get, dp_clks);
++      if (ret)
++              return ret;
++
++      /*
++       * Roll a devm action because the clock provider is the child node, but
++       * the child node is not actually a device.
++       */
++      return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
++}
++
++static const struct phy_ops qcom_qmp_phy_gen_ops = {
++      .init           = qcom_qmp_phy_enable,
++      .exit           = qcom_qmp_phy_disable,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static const struct phy_ops qcom_qmp_phy_dp_ops = {
++      .init           = qcom_qmp_phy_init,
++      .configure      = qcom_qmp_dp_phy_configure,
++      .power_on       = qcom_qmp_phy_power_on,
++      .calibrate      = qcom_qmp_dp_phy_calibrate,
++      .power_off      = qcom_qmp_phy_power_off,
++      .exit           = qcom_qmp_phy_exit,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static const struct phy_ops qcom_qmp_pcie_ufs_ops = {
++      .power_on       = qcom_qmp_phy_enable,
++      .power_off      = qcom_qmp_phy_disable,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static void qcom_qmp_reset_control_put(void *data)
++{
++      reset_control_put(data);
++}
++
++static
++int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id,
++                      void __iomem *serdes, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct phy *generic_phy;
++      struct qmp_phy *qphy;
++      const struct phy_ops *ops;
++      char prop_name[MAX_PROP_NAME];
++      int ret;
++
++      qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
++      if (!qphy)
++              return -ENOMEM;
++
++      qphy->cfg = cfg;
++      qphy->serdes = serdes;
++      /*
++       * Get memory resources for each phy lane:
++       * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
++       * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
++       * For single lane PHYs: pcs_misc (optional) -> 3.
++       */
++      qphy->tx = of_iomap(np, 0);
++      if (!qphy->tx)
++              return -ENOMEM;
++
++      qphy->rx = of_iomap(np, 1);
++      if (!qphy->rx)
++              return -ENOMEM;
++
++      qphy->pcs = of_iomap(np, 2);
++      if (!qphy->pcs)
++              return -ENOMEM;
++
++      /*
++       * If this is a dual-lane PHY, then there should be registers for the
++       * second lane. Some old device trees did not specify this, so fall
++       * back to old legacy behavior of assuming they can be reached at an
++       * offset from the first lane.
++       */
++      if (cfg->is_dual_lane_phy) {
++              qphy->tx2 = of_iomap(np, 3);
++              qphy->rx2 = of_iomap(np, 4);
++              if (!qphy->tx2 || !qphy->rx2) {
++                      dev_warn(dev,
++                               "Underspecified device tree, falling back to legacy register regions\n");
++
++                      /* In the old version, pcs_misc is at index 3. */
++                      qphy->pcs_misc = qphy->tx2;
++                      qphy->tx2 = qphy->tx + QMP_PHY_LEGACY_LANE_STRIDE;
++                      qphy->rx2 = qphy->rx + QMP_PHY_LEGACY_LANE_STRIDE;
++
++              } else {
++                      qphy->pcs_misc = of_iomap(np, 5);
++              }
++
++      } else {
++              qphy->pcs_misc = of_iomap(np, 3);
++      }
++
++      if (!qphy->pcs_misc)
++              dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
++
++      /*
++       * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3
++       * based phys, so they essentially have pipe clock. So,
++       * we return error in case phy is USB3 or PIPE type.
++       * Otherwise, we initialize pipe clock to NULL for
++       * all phys that don't need this.
++       */
++      snprintf(prop_name, sizeof(prop_name), "pipe%d", id);
++      qphy->pipe_clk = devm_get_clk_from_child(dev, np, prop_name);
++      if (IS_ERR(qphy->pipe_clk)) {
++              if (cfg->type == PHY_TYPE_PCIE ||
++                  cfg->type == PHY_TYPE_USB3) {
++                      ret = PTR_ERR(qphy->pipe_clk);
++                      if (ret != -EPROBE_DEFER)
++                              dev_err(dev,
++                                      "failed to get lane%d pipe_clk, %d\n",
++                                      id, ret);
++                      return ret;
++              }
++              qphy->pipe_clk = NULL;
++      }
++
++      /* Get lane reset, if any */
++      if (cfg->has_lane_rst) {
++              snprintf(prop_name, sizeof(prop_name), "lane%d", id);
++              qphy->lane_rst = of_reset_control_get_exclusive(np, prop_name);
++              if (IS_ERR(qphy->lane_rst)) {
++                      dev_err(dev, "failed to get lane%d reset\n", id);
++                      return PTR_ERR(qphy->lane_rst);
++              }
++              ret = devm_add_action_or_reset(dev, qcom_qmp_reset_control_put,
++                                             qphy->lane_rst);
++              if (ret)
++                      return ret;
++      }
++
++      if (cfg->type == PHY_TYPE_UFS || cfg->type == PHY_TYPE_PCIE)
++              ops = &qcom_qmp_pcie_ufs_ops;
++      else if (cfg->type == PHY_TYPE_DP)
++              ops = &qcom_qmp_phy_dp_ops;
++      else
++              ops = &qcom_qmp_phy_gen_ops;
++
++      generic_phy = devm_phy_create(dev, np, ops);
++      if (IS_ERR(generic_phy)) {
++              ret = PTR_ERR(generic_phy);
++              dev_err(dev, "failed to create qphy %d\n", ret);
++              return ret;
++      }
++
++      qphy->phy = generic_phy;
++      qphy->index = id;
++      qphy->qmp = qmp;
++      qmp->phys[id] = qphy;
++      phy_set_drvdata(generic_phy, qphy);
++
++      return 0;
++}
++
++static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
++      {
++              .compatible = "qcom,ipq8074-qmp-usb3-phy",
++              .data = &ipq8074_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-pcie-phy",
++              .data = &msm8996_pciephy_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-ufs-phy",
++              .data = &msm8996_ufs_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-usb3-phy",
++              .data = &msm8996_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-pcie-phy",
++              .data = &msm8998_pciephy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,ipq8074-qmp-pcie-phy",
++              .data = &ipq8074_pciephy_cfg,
++      }, {
++              .compatible = "qcom,ipq6018-qmp-pcie-phy",
++              .data = &ipq6018_pciephy_cfg,
++      }, {
++              .compatible = "qcom,ipq6018-qmp-usb3-phy",
++              .data = &ipq8074_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc7180-qmp-usb3-phy",
++              .data = &sc7180_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sc8180x-qmp-pcie-phy",
++              .data = &sc8180x_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sc8280xp-qmp-ufs-phy",
++              .data = &sm8350_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-usb3-phy",
++              .data = &sm8150_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sdm845-qhp-pcie-phy",
++              .data = &sdm845_qhp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-pcie-phy",
++              .data = &sdm845_qmp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-usb3-phy",
++              .data = &qmp_v3_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-usb3-uni-phy",
++              .data = &qmp_v3_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-usb3-phy",
++              .data = &msm8998_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm6115-qmp-ufs-phy",
++              .data = &sm6115_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm6350-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-usb3-phy",
++              .data = &sm8150_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-usb3-uni-phy",
++              .data = &sm8150_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-phy",
++              .data = &sm8250_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-uni-phy",
++              .data = &sm8250_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy",
++              .data = &sm8250_qmp_gen3x1_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-gen3x2-pcie-phy",
++              .data = &sm8250_qmp_gen3x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-ufs-phy",
++              .data = &sm8350_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-modem-pcie-phy",
++              .data = &sm8250_qmp_gen3x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdx55-qmp-pcie-phy",
++              .data = &sdx55_qmp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdx55-qmp-usb3-uni-phy",
++              .data = &sdx55_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sdx65-qmp-usb3-uni-phy",
++              .data = &sdx65_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-usb3-phy",
++              .data = &sm8350_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-usb3-uni-phy",
++              .data = &sm8350_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-gen3x1-pcie-phy",
++              .data = &sm8450_qmp_gen3x1_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-gen4x2-pcie-phy",
++              .data = &sm8450_qmp_gen4x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-ufs-phy",
++              .data = &sm8450_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-usb3-phy",
++              .data = &sm8350_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,qcm2290-qmp-usb3-phy",
++              .data = &qcm2290_usb3phy_cfg,
++      },
++      { },
++};
++MODULE_DEVICE_TABLE(of, qcom_qmp_phy_of_match_table);
++
++static const struct of_device_id qcom_qmp_combo_phy_of_match_table[] = {
++      {
++              .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
++              .data = &sc7180_usb3dpphy_cfg,
++      },
++      {
++              .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
++              .data = &sm8250_usb3dpphy_cfg,
++      },
++      {
++              .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
++              .data = &sc8180x_usb3dpphy_cfg,
++      },
++      { }
++};
++
++static const struct dev_pm_ops qcom_qmp_phy_pm_ops = {
++      SET_RUNTIME_PM_OPS(qcom_qmp_phy_runtime_suspend,
++                         qcom_qmp_phy_runtime_resume, NULL)
++};
++
++static int qcom_qmp_phy_probe(struct platform_device *pdev)
++{
++      struct qcom_qmp *qmp;
++      struct device *dev = &pdev->dev;
++      struct device_node *child;
++      struct phy_provider *phy_provider;
++      void __iomem *serdes;
++      void __iomem *usb_serdes;
++      void __iomem *dp_serdes = NULL;
++      const struct qmp_phy_combo_cfg *combo_cfg = NULL;
++      const struct qmp_phy_cfg *cfg = NULL;
++      const struct qmp_phy_cfg *usb_cfg = NULL;
++      const struct qmp_phy_cfg *dp_cfg = NULL;
++      int num, id, expected_phys;
++      int ret;
++
++      qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
++      if (!qmp)
++              return -ENOMEM;
++
++      qmp->dev = dev;
++      dev_set_drvdata(dev, qmp);
++
++      /* Get the specific init parameters of QMP phy */
++      cfg = of_device_get_match_data(dev);
++      if (!cfg) {
++              const struct of_device_id *match;
++
++              match = of_match_device(qcom_qmp_combo_phy_of_match_table, dev);
++              if (!match)
++                      return -EINVAL;
++
++              combo_cfg = match->data;
++              if (!combo_cfg)
++                      return -EINVAL;
++
++              usb_cfg = combo_cfg->usb_cfg;
++              cfg = usb_cfg; /* Setup clks and regulators */
++      }
++
++      /* per PHY serdes; usually located at base address */
++      usb_serdes = serdes = devm_platform_ioremap_resource(pdev, 0);
++      if (IS_ERR(serdes))
++              return PTR_ERR(serdes);
++
++      /* per PHY dp_com; if PHY has dp_com control block */
++      if (combo_cfg || cfg->has_phy_dp_com_ctrl) {
++              qmp->dp_com = devm_platform_ioremap_resource(pdev, 1);
++              if (IS_ERR(qmp->dp_com))
++                      return PTR_ERR(qmp->dp_com);
++      }
++
++      if (combo_cfg) {
++              /* Only two serdes for combo PHY */
++              dp_serdes = devm_platform_ioremap_resource(pdev, 2);
++              if (IS_ERR(dp_serdes))
++                      return PTR_ERR(dp_serdes);
++
++              dp_cfg = combo_cfg->dp_cfg;
++              expected_phys = 2;
++      } else {
++              expected_phys = cfg->nlanes;
++      }
++
++      mutex_init(&qmp->phy_mutex);
++
++      ret = qcom_qmp_phy_clk_init(dev, cfg);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_reset_init(dev, cfg);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_vreg_init(dev, cfg);
++      if (ret) {
++              if (ret != -EPROBE_DEFER)
++                      dev_err(dev, "failed to get regulator supplies: %d\n",
++                              ret);
++              return ret;
++      }
++
++      num = of_get_available_child_count(dev->of_node);
++      /* do we have a rogue child node ? */
++      if (num > expected_phys)
++              return -EINVAL;
++
++      qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
++      if (!qmp->phys)
++              return -ENOMEM;
++
++      pm_runtime_set_active(dev);
++      pm_runtime_enable(dev);
++      /*
++       * Prevent runtime pm from being ON by default. Users can enable
++       * it using power/control in sysfs.
++       */
++      pm_runtime_forbid(dev);
++
++      id = 0;
++      for_each_available_child_of_node(dev->of_node, child) {
++              if (of_node_name_eq(child, "dp-phy")) {
++                      cfg = dp_cfg;
++                      serdes = dp_serdes;
++              } else if (of_node_name_eq(child, "usb3-phy")) {
++                      cfg = usb_cfg;
++                      serdes = usb_serdes;
++              }
++
++              /* Create per-lane phy */
++              ret = qcom_qmp_phy_create(dev, child, id, serdes, cfg);
++              if (ret) {
++                      dev_err(dev, "failed to create lane%d phy, %d\n",
++                              id, ret);
++                      goto err_node_put;
++              }
++
++              /*
++               * Register the pipe clock provided by phy.
++               * See function description to see details of this pipe clock.
++               */
++              if (cfg->type == PHY_TYPE_USB3 || cfg->type == PHY_TYPE_PCIE) {
++                      ret = phy_pipe_clk_register(qmp, child);
++                      if (ret) {
++                              dev_err(qmp->dev,
++                                      "failed to register pipe clock source\n");
++                              goto err_node_put;
++                      }
++              } else if (cfg->type == PHY_TYPE_DP) {
++                      ret = phy_dp_clks_register(qmp, qmp->phys[id], child);
++                      if (ret) {
++                              dev_err(qmp->dev,
++                                      "failed to register DP clock source\n");
++                              goto err_node_put;
++                      }
++              }
++              id++;
++      }
++
++      phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
++      if (!IS_ERR(phy_provider))
++              dev_info(dev, "Registered Qcom-QMP phy\n");
++      else
++              pm_runtime_disable(dev);
++
++      return PTR_ERR_OR_ZERO(phy_provider);
++
++err_node_put:
++      pm_runtime_disable(dev);
++      of_node_put(child);
++      return ret;
++}
++
++static struct platform_driver qcom_qmp_phy_driver = {
++      .probe          = qcom_qmp_phy_probe,
++      .driver = {
++              .name   = "qcom-qmp-phy",
++              .pm     = &qcom_qmp_phy_pm_ops,
++              .of_match_table = qcom_qmp_phy_of_match_table,
++      },
++};
++
++module_platform_driver(qcom_qmp_phy_driver);
++
++MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
++MODULE_DESCRIPTION("Qualcomm QMP PHY driver");
++MODULE_LICENSE("GPL v2");
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+new file mode 100644
+index 000000000000..c7309e981bfb
+--- /dev/null
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+@@ -0,0 +1,6350 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++
++#include <dt-bindings/phy/phy.h>
++
++#include "phy-qcom-qmp.h"
++
++/* QPHY_SW_RESET bit */
++#define SW_RESET                              BIT(0)
++/* QPHY_POWER_DOWN_CONTROL */
++#define SW_PWRDN                              BIT(0)
++#define REFCLK_DRV_DSBL                               BIT(1)
++/* QPHY_START_CONTROL bits */
++#define SERDES_START                          BIT(0)
++#define PCS_START                             BIT(1)
++#define PLL_READY_GATE_EN                     BIT(3)
++/* QPHY_PCS_STATUS bit */
++#define PHYSTATUS                             BIT(6)
++#define PHYSTATUS_4_20                                BIT(7)
++/* QPHY_PCS_READY_STATUS & QPHY_COM_PCS_READY_STATUS bit */
++#define PCS_READY                             BIT(0)
++
++/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
++/* DP PHY soft reset */
++#define SW_DPPHY_RESET                                BIT(0)
++/* mux to select DP PHY reset control, 0:HW control, 1: software reset */
++#define SW_DPPHY_RESET_MUX                    BIT(1)
++/* USB3 PHY soft reset */
++#define SW_USB3PHY_RESET                      BIT(2)
++/* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
++#define SW_USB3PHY_RESET_MUX                  BIT(3)
++
++/* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
++#define USB3_MODE                             BIT(0) /* enables USB3 mode */
++#define DP_MODE                                       BIT(1) /* enables DP mode */
++
++/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
++#define ARCVR_DTCT_EN                         BIT(0)
++#define ALFPS_DTCT_EN                         BIT(1)
++#define ARCVR_DTCT_EVENT_SEL                  BIT(4)
++
++/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
++#define IRQ_CLEAR                             BIT(0)
++
++/* QPHY_PCS_LFPS_RXTERM_IRQ_STATUS register bits */
++#define RCVR_DETECT                           BIT(0)
++
++/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
++#define CLAMP_EN                              BIT(0) /* enables i/o clamp_n */
++
++#define PHY_INIT_COMPLETE_TIMEOUT             10000
++#define POWER_DOWN_DELAY_US_MIN                       10
++#define POWER_DOWN_DELAY_US_MAX                       11
++
++#define MAX_PROP_NAME                         32
++
++/* Define the assumed distance between lanes for underspecified device trees. */
++#define QMP_PHY_LEGACY_LANE_STRIDE            0x400
++
++struct qmp_phy_init_tbl {
++      unsigned int offset;
++      unsigned int val;
++      /*
++       * register part of layout ?
++       * if yes, then offset gives index in the reg-layout
++       */
++      bool in_layout;
++      /*
++       * mask of lanes for which this register is written
++       * for cases when second lane needs different values
++       */
++      u8 lane_mask;
++};
++
++#define QMP_PHY_INIT_CFG(o, v)                \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .lane_mask = 0xff,      \
++      }
++
++#define QMP_PHY_INIT_CFG_L(o, v)      \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .in_layout = true,      \
++              .lane_mask = 0xff,      \
++      }
++
++#define QMP_PHY_INIT_CFG_LANE(o, v, l)        \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .lane_mask = l,         \
++      }
++
++/* set of registers with offsets different per-PHY */
++enum qphy_reg_layout {
++      /* Common block control registers */
++      QPHY_COM_SW_RESET,
++      QPHY_COM_POWER_DOWN_CONTROL,
++      QPHY_COM_START_CONTROL,
++      QPHY_COM_PCS_READY_STATUS,
++      /* PCS registers */
++      QPHY_PLL_LOCK_CHK_DLY_TIME,
++      QPHY_FLL_CNTRL1,
++      QPHY_FLL_CNTRL2,
++      QPHY_FLL_CNT_VAL_L,
++      QPHY_FLL_CNT_VAL_H_TOL,
++      QPHY_FLL_MAN_CODE,
++      QPHY_SW_RESET,
++      QPHY_START_CTRL,
++      QPHY_PCS_READY_STATUS,
++      QPHY_PCS_STATUS,
++      QPHY_PCS_AUTONOMOUS_MODE_CTRL,
++      QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
++      QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
++      QPHY_PCS_POWER_DOWN_CONTROL,
++      /* PCS_MISC registers */
++      QPHY_PCS_MISC_TYPEC_CTRL,
++      /* Keep last to ensure regs_layout arrays are properly initialized */
++      QPHY_LAYOUT_SIZE
++};
++
++static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x168,
++};
++
++static const unsigned int ipq_pciephy_gen3_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                         = 0x00,
++      [QPHY_START_CTRL]                       = 0x44,
++      [QPHY_PCS_STATUS]                       = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]           = 0x40,
++};
++
++static const unsigned int pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_COM_SW_RESET]             = 0x400,
++      [QPHY_COM_POWER_DOWN_CONTROL]   = 0x404,
++      [QPHY_COM_START_CONTROL]        = 0x408,
++      [QPHY_COM_PCS_READY_STATUS]     = 0x448,
++      [QPHY_PLL_LOCK_CHK_DLY_TIME]    = 0xa8,
++      [QPHY_FLL_CNTRL1]               = 0xc4,
++      [QPHY_FLL_CNTRL2]               = 0xc8,
++      [QPHY_FLL_CNT_VAL_L]            = 0xcc,
++      [QPHY_FLL_CNT_VAL_H_TOL]        = 0xd0,
++      [QPHY_FLL_MAN_CODE]             = 0xd4,
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++};
++
++static const unsigned int usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_FLL_CNTRL1]               = 0xc0,
++      [QPHY_FLL_CNTRL2]               = 0xc4,
++      [QPHY_FLL_CNT_VAL_L]            = 0xc8,
++      [QPHY_FLL_CNT_VAL_H_TOL]        = 0xcc,
++      [QPHY_FLL_MAN_CODE]             = 0xd0,
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x17c,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d4,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0d8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178,
++};
++
++static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0dc,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
++};
++
++static const unsigned int sdm845_qmp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++};
++
++static const unsigned int sdm845_qhp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x2ac,
++};
++
++static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x308,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x314,
++};
++
++static const unsigned int qmp_v4_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x608,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x614,
++};
++
++static const unsigned int sm8350_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x1008,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x1014,
++};
++
++static const unsigned int qcm2290_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x04,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0xd8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0xdc,
++      [QPHY_PCS_STATUS]               = 0x174,
++      [QPHY_PCS_MISC_TYPEC_CTRL]      = 0x00,
++};
++
++static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x160,
++};
++
++static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x168,
++};
++
++static const unsigned int sm8250_pcie_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++};
++
++static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = QPHY_V4_PCS_UFS_PHY_START,
++      [QPHY_PCS_READY_STATUS]         = QPHY_V4_PCS_UFS_READY_STATUS,
++      [QPHY_SW_RESET]                 = QPHY_V4_PCS_UFS_SW_RESET,
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      /* PLL and Loop filter settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      /* SSC settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x0),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x40),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x19),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_RX_IDLE_DTCT_CNTRL, 0x4c),
++      QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++
++      QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x05),
++
++      QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x05),
++      QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG4, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG1, 0xa3),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0x0e),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x7e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x15),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x40),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x99),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x04),
++      /* PLL and Loop filter settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      /* SSC settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xbb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL2, 0x03),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_H_TOL, 0x42),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_MAN_CODE, 0x85),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG2, 0x08),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x29),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x53),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_TX0_LANE_MODE_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_TX0_RCV_DETECT_LVL_2, 0x12),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_GAIN, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0x61),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_LOW, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH2, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH3, 0xd3),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH4, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_LOW, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_DFE_EN_TIMER, 0x04),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL1, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(PCS_COM_G12S1_TXDEEMPH_M3P5DB, 0x10),
++      QMP_PHY_INIT_CFG(PCS_COM_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_RX_DCC_CAL_CONFIG, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_EQ_CONFIG5, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
++      QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
++      QMP_PHY_INIT_CFG(PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++      QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG1, 0x11),
++      QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_POST, 0x58),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0xf),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0xf),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x3),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0xD),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xD04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0xb),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x6),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_TX_EMP_POST1_LVL, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_TX_SLEW_CNTL, 0x0a),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x4),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x4),
++      QMP_PHY_INIT_CFG(QPHY_OSC_DTCT_ACTIONS, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x40),
++      QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x73),
++      QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_LVL, 0x99),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0xe),
++      QMP_PHY_INIT_CFG_L(QPHY_SW_RESET, 0x0),
++      QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x007),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x7e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x15),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_01, 0x59),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x40),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE, 0x04),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xbb),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG4, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_CONFIG2, 0x52),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG2, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG4, 0x1a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG5, 0x06),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SYSCLK_EN_SEL, 0x27),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE2, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BIAS_EN_CKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CLK_ENABLE1, 0xb0),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP1_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP2_MODE0, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_RESTRIM_CTRL2, 0x05),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VCO_TUNE_MAP, 0x10),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CLK_SELECT, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_HSCLK_SEL1, 0x30),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORECLK_DIV, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORE_CLK_EN, 0x73),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CMN_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SVS_MODE_CLK_SEL, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VREGCLK_DIV1, 0x22),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VREGCLK_DIV2, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BGV_TRIM, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BG_CTRL, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL0, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_TAP_EN, 0x0d),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_TX_BAND_MODE, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_LANE_MODE, 0x1a),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PARALLEL_RATE, 0x2f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE0, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE1, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE2, 0x1b),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PREAMP_CTRL_MODE1, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PREAMP_CTRL_MODE2, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE0, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE1, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE2, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_THRESH_DFE, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CGA_THRESH_DFE, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXENGINE_EN0, 0x12),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_TRAIN_TIME, 0x25),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_DFE_OVRLP_TIME, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_REFRESH_TIME, 0x05),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_ENABLE_TIME, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_VGA_GAIN, 0x26),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_GAIN, 0x12),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EQ_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_OFFSET_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PRE_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EQ_INTVAL, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EDAC_INITVAL, 0x28),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_INITB0, 0x7f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_INITB1, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RCVRDONE_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_CTRL, 0x70),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE0, 0x8b),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE2, 0x0a),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE2, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_BAND, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE0, 0x5c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE1, 0x3e),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE2, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_ENABLES, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_CNTRL, 0xa0),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_DEGLITCH_CNTRL, 0x08),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DCC_GAIN, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_EN_SIGNAL, 0xc3),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PSM_RX_EN_CAL, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_MISC_CNTRL0, 0xbc),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_TS0_TIMER, 0x7f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DLL_HIGHDATARATE, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RESETCODE_OFFSET, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_VGA_INITVAL, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RSM_START, 0x01),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_rx_tbl[] = {
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_PCS_TX_RX_CONFIG, 0x50),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_MAIN_V0_M3P5DB, 0x19),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_POST_V0_M3P5DB, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_MAIN_V0_M6DB, 0x17),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_POST_V0_M6DB, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG5, 0x9f),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_rbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x6f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr2[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr3[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRANSCEIVER_BIAS_EN, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_VMODE_CTRL1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_INTERFACE_SELECT, 0x3d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_CLKBUF_ENABLE, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RESET_TSYNC_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRAN_DRVR_EMP_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_BAND, 0x4),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_POL_INV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_DRV_LVL, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_EMP_POST1_LVL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb5),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4c),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x64),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_RX_PWM_GEAR_BAND, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_DRV_LVL, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
++      QMP_PHY_INIT_CFG(QPHY_RX_SYM_RESYNC_CTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
++      QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_CTRL2, 0x6e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SYM_RESYNC_CTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_CTRL1, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_MIN_HIBERN8_TIME, 0x9a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_INITVAL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x43),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x8a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
++
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x94),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_pcs_tbl[] = {
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x95),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xef),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x60),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x60),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x40, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x54, 2),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0xff, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f, 2),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff, 2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x97),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORE_CLK_EN, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_rbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x6f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr2[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr3[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_VMODE_CTRL1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_INTERFACE_SELECT, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_CLKBUF_ENABLE, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RESET_TSYNC_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_BAND, 0x4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_POL_INV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_DRV_LVL, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_EMP_POST1_LVL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x5),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x6e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x6e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x39),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x39),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x01),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x35),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x30),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x12),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE, 0x33),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x05),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG2, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x08),
++};
++
++static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x26),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x048),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x46),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_CFG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x50),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MISC1, 0x88),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTERNAL_DIG_CORECLK_DIV, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MODE, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_DC_LEVEL_CTRL, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x56),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x22),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_3, 0x13),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_VMODE_CTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_PI_QEC_CTRL, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_FO_GAIN_RATE2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_UCDR_PI_CONTROLS, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_AUX_DATA_TCOARSE_TFINE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_3, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_VGA_CAL_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B1, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B2, 0x5a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B4, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B0, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B1, 0xf9),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B3, 0xce),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B4, 0x62),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B0, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B1, 0x7d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B3, 0xcf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B4, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_PHPRE_CTRL, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_MARG_COARSE_CTRL2, 0x12),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG2, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG4, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG5, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_EQ_CONFIG1, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G3_RXEQEVAL_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_RXEQEVAL_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG2, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_SW_CTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_MX_CTRL2, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdx65_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0b),
++};
++
++static const struct qmp_phy_init_tbl sdx65_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_ENABLES, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_PLL_CNTL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_RX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x35),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_5, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xbb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbb),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3d, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3c, 2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xd2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x13),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_ENABLES, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_INITVAL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x01),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x04),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xd8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_TX_ADAPT_POST_THRESH, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RATE_SLEW_CNTRL1, 0x0b),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG2, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x97),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x46),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_CFG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0xd0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MISC1, 0x88),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORE_CLK_EN, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MODE, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_DC_LEVEL_CTRL, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_PI_CONTROLS, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B1, 0xcc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B3, 0xcc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B5, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B6, 0x29),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B0, 0xc5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B1, 0xad),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B2, 0xb6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B3, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B4, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B5, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B6, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B0, 0xc7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B1, 0xef),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B3, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B4, 0x81),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B5, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B6, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_PHPRE_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_0_1, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_2_3, 0x37),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_3, 0x05),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE3, 0x1f),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE210, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE210, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE210, 0x1f),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE3, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_VGA_CAL_MAN_VAL, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_IDAC_SAOFFSET, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_DAC_ENABLE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_GM_CAL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH2, 0x1f),
++};
++
++/* Register names should be validated, they might be different for this PHY */
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG2, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG3, 0x22),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_G3S2_PRE_GAIN, 0x2e),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x99),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_EQ_CONFIG1, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_RX_MARGINING_CONFIG3, 0x28),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_PRE_GAIN, 0x2e),
++};
++
++struct qmp_phy;
++
++/* struct qmp_phy_cfg - per-PHY initialization config */
++struct qmp_phy_cfg {
++      /* phy-type - PCIE/UFS/USB */
++      unsigned int type;
++      /* number of lanes provided by phy */
++      int nlanes;
++
++      /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
++      const struct qmp_phy_init_tbl *serdes_tbl;
++      int serdes_tbl_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_sec;
++      int serdes_tbl_num_sec;
++      const struct qmp_phy_init_tbl *tx_tbl;
++      int tx_tbl_num;
++      const struct qmp_phy_init_tbl *tx_tbl_sec;
++      int tx_tbl_num_sec;
++      const struct qmp_phy_init_tbl *rx_tbl;
++      int rx_tbl_num;
++      const struct qmp_phy_init_tbl *rx_tbl_sec;
++      int rx_tbl_num_sec;
++      const struct qmp_phy_init_tbl *pcs_tbl;
++      int pcs_tbl_num;
++      const struct qmp_phy_init_tbl *pcs_tbl_sec;
++      int pcs_tbl_num_sec;
++      const struct qmp_phy_init_tbl *pcs_misc_tbl;
++      int pcs_misc_tbl_num;
++      const struct qmp_phy_init_tbl *pcs_misc_tbl_sec;
++      int pcs_misc_tbl_num_sec;
++
++      /* Init sequence for DP PHY block link rates */
++      const struct qmp_phy_init_tbl *serdes_tbl_rbr;
++      int serdes_tbl_rbr_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr;
++      int serdes_tbl_hbr_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr2;
++      int serdes_tbl_hbr2_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr3;
++      int serdes_tbl_hbr3_num;
++
++      /* DP PHY callbacks */
++      int (*configure_dp_phy)(struct qmp_phy *qphy);
++      void (*configure_dp_tx)(struct qmp_phy *qphy);
++      int (*calibrate_dp_phy)(struct qmp_phy *qphy);
++      void (*dp_aux_init)(struct qmp_phy *qphy);
++
++      /* clock ids to be requested */
++      const char * const *clk_list;
++      int num_clks;
++      /* resets to be requested */
++      const char * const *reset_list;
++      int num_resets;
++      /* regulators to be requested */
++      const char * const *vreg_list;
++      int num_vregs;
++
++      /* array of registers with different offsets */
++      const unsigned int *regs;
++
++      unsigned int start_ctrl;
++      unsigned int pwrdn_ctrl;
++      unsigned int mask_com_pcs_ready;
++      /* bit offset of PHYSTATUS in QPHY_PCS_STATUS register */
++      unsigned int phy_status;
++
++      /* true, if PHY has a separate PHY_COM control block */
++      bool has_phy_com_ctrl;
++      /* true, if PHY has a reset for individual lanes */
++      bool has_lane_rst;
++      /* true, if PHY needs delay after POWER_DOWN */
++      bool has_pwrdn_delay;
++      /* power_down delay in usec */
++      int pwrdn_delay_min;
++      int pwrdn_delay_max;
++
++      /* true, if PHY has a separate DP_COM control block */
++      bool has_phy_dp_com_ctrl;
++      /* true, if PHY has secondary tx/rx lanes to be configured */
++      bool is_dual_lane_phy;
++
++      /* true, if PCS block has no separate SW_RESET register */
++      bool no_pcs_sw_reset;
++};
++
++struct qmp_phy_combo_cfg {
++      const struct qmp_phy_cfg *usb_cfg;
++      const struct qmp_phy_cfg *dp_cfg;
++};
++
++/**
++ * struct qmp_phy - per-lane phy descriptor
++ *
++ * @phy: generic phy
++ * @cfg: phy specific configuration
++ * @serdes: iomapped memory space for phy's serdes (i.e. PLL)
++ * @tx: iomapped memory space for lane's tx
++ * @rx: iomapped memory space for lane's rx
++ * @pcs: iomapped memory space for lane's pcs
++ * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
++ * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
++ * @pcs_misc: iomapped memory space for lane's pcs_misc
++ * @pipe_clk: pipe clock
++ * @index: lane index
++ * @qmp: QMP phy to which this lane belongs
++ * @lane_rst: lane's reset controller
++ * @mode: current PHY mode
++ * @dp_aux_cfg: Display port aux config
++ * @dp_opts: Display port optional config
++ * @dp_clks: Display port clocks
++ */
++struct qmp_phy {
++      struct phy *phy;
++      const struct qmp_phy_cfg *cfg;
++      void __iomem *serdes;
++      void __iomem *tx;
++      void __iomem *rx;
++      void __iomem *pcs;
++      void __iomem *tx2;
++      void __iomem *rx2;
++      void __iomem *pcs_misc;
++      struct clk *pipe_clk;
++      unsigned int index;
++      struct qcom_qmp *qmp;
++      struct reset_control *lane_rst;
++      enum phy_mode mode;
++      unsigned int dp_aux_cfg;
++      struct phy_configure_opts_dp dp_opts;
++      struct qmp_phy_dp_clks *dp_clks;
++};
++
++struct qmp_phy_dp_clks {
++      struct qmp_phy *qphy;
++      struct clk_hw dp_link_hw;
++      struct clk_hw dp_pixel_hw;
++};
++
++/**
++ * struct qcom_qmp - structure holding QMP phy block attributes
++ *
++ * @dev: device
++ * @dp_com: iomapped memory space for phy's dp_com control block
++ *
++ * @clks: array of clocks required by phy
++ * @resets: array of resets required by phy
++ * @vregs: regulator supplies bulk data
++ *
++ * @phys: array of per-lane phy descriptors
++ * @phy_mutex: mutex lock for PHY common block initialization
++ * @init_count: phy common block initialization count
++ * @ufs_reset: optional UFS PHY reset handle
++ */
++struct qcom_qmp {
++      struct device *dev;
++      void __iomem *dp_com;
++
++      struct clk_bulk_data *clks;
++      struct reset_control **resets;
++      struct regulator_bulk_data *vregs;
++
++      struct qmp_phy **phys;
++
++      struct mutex phy_mutex;
++      int init_count;
++
++      struct reset_control *ufs_reset;
++};
++
++static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy);
++static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy);
++static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy);
++static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy);
++
++static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy);
++static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy);
++static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy);
++static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy);
++
++static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
++{
++      u32 reg;
++
++      reg = readl(base + offset);
++      reg |= val;
++      writel(reg, base + offset);
++
++      /* ensure that above write is through */
++      readl(base + offset);
++}
++
++static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
++{
++      u32 reg;
++
++      reg = readl(base + offset);
++      reg &= ~val;
++      writel(reg, base + offset);
++
++      /* ensure that above write is through */
++      readl(base + offset);
++}
++
++/* list of clocks required by phy */
++static const char * const msm8996_phy_clk_l[] = {
++      "aux", "cfg_ahb", "ref",
++};
++
++static const char * const msm8996_ufs_phy_clk_l[] = {
++      "ref",
++};
++
++static const char * const qmp_v3_phy_clk_l[] = {
++      "aux", "cfg_ahb", "ref", "com_aux",
++};
++
++static const char * const sdm845_pciephy_clk_l[] = {
++      "aux", "cfg_ahb", "ref", "refgen",
++};
++
++static const char * const qmp_v4_phy_clk_l[] = {
++      "aux", "ref_clk_src", "ref", "com_aux",
++};
++
++/* the primary usb3 phy on sm8250 doesn't have a ref clock */
++static const char * const qmp_v4_sm8250_usbphy_clk_l[] = {
++      "aux", "ref_clk_src", "com_aux"
++};
++
++static const char * const sm8450_ufs_phy_clk_l[] = {
++      "qref", "ref", "ref_aux",
++};
++
++static const char * const sdm845_ufs_phy_clk_l[] = {
++      "ref", "ref_aux",
++};
++
++/* usb3 phy on sdx55 doesn't have com_aux clock */
++static const char * const qmp_v4_sdx55_usbphy_clk_l[] = {
++      "aux", "cfg_ahb", "ref"
++};
++
++static const char * const qcm2290_usb3phy_clk_l[] = {
++      "cfg_ahb", "ref", "com_aux",
++};
++
++/* list of resets */
++static const char * const msm8996_pciephy_reset_l[] = {
++      "phy", "common", "cfg",
++};
++
++static const char * const msm8996_usb3phy_reset_l[] = {
++      "phy", "common",
++};
++
++static const char * const sc7180_usb3phy_reset_l[] = {
++      "phy",
++};
++
++static const char * const qcm2290_usb3phy_reset_l[] = {
++      "phy_phy", "phy",
++};
++
++static const char * const sdm845_pciephy_reset_l[] = {
++      "phy",
++};
++
++/* list of regulators */
++static const char * const qmp_phy_vreg_l[] = {
++      "vdda-phy", "vdda-pll",
++};
++
++static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq8074_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq8074_usb3_serdes_tbl),
++      .tx_tbl                 = msm8996_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_usb3_tx_tbl),
++      .rx_tbl                 = ipq8074_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq8074_usb3_rx_tbl),
++      .pcs_tbl                = ipq8074_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq8074_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++};
++
++static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 3,
++
++      .serdes_tbl             = msm8996_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_pcie_serdes_tbl),
++      .tx_tbl                 = msm8996_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_pcie_tx_tbl),
++      .rx_tbl                 = msm8996_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_pcie_rx_tbl),
++      .pcs_tbl                = msm8996_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8996_pcie_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | PLL_READY_GATE_EN,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .mask_com_pcs_ready     = PCS_READY,
++      .phy_status             = PHYSTATUS,
++
++      .has_phy_com_ctrl       = true,
++      .has_lane_rst           = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg msm8996_ufs_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8996_ufs_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_ufs_serdes_tbl),
++      .tx_tbl                 = msm8996_ufs_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_ufs_tx_tbl),
++      .rx_tbl                 = msm8996_ufs_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_ufs_rx_tbl),
++
++      .clk_list               = msm8996_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_ufs_phy_clk_l),
++
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++
++      .regs                   = msm8996_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8996_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_usb3_serdes_tbl),
++      .tx_tbl                 = msm8996_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_usb3_tx_tbl),
++      .rx_tbl                 = msm8996_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_usb3_rx_tbl),
++      .pcs_tbl                = msm8996_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8996_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++};
++
++static const char * const ipq8074_pciephy_clk_l[] = {
++      "aux", "cfg_ahb",
++};
++/* list of resets */
++static const char * const ipq8074_pciephy_reset_l[] = {
++      "phy", "common",
++};
++
++static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq8074_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq8074_pcie_serdes_tbl),
++      .tx_tbl                 = ipq8074_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_tx_tbl),
++      .rx_tbl                 = ipq8074_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_rx_tbl),
++      .pcs_tbl                = ipq8074_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq8074_pcie_pcs_tbl),
++      .clk_list               = ipq8074_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(ipq8074_pciephy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = NULL,
++      .num_vregs              = 0,
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_phy_com_ctrl       = false,
++      .has_lane_rst           = false,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq6018_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq6018_pcie_serdes_tbl),
++      .tx_tbl                 = ipq6018_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(ipq6018_pcie_tx_tbl),
++      .rx_tbl                 = ipq6018_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq6018_pcie_rx_tbl),
++      .pcs_tbl                = ipq6018_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq6018_pcie_pcs_tbl),
++      .clk_list               = ipq8074_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(ipq8074_pciephy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = NULL,
++      .num_vregs              = 0,
++      .regs                   = ipq_pciephy_gen3_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++
++      .has_phy_com_ctrl       = false,
++      .has_lane_rst           = false,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sdm845_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sdm845_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sdm845_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sdm845_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sdm845_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sdm845_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_qmp_pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdm845_qhp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sdm845_qhp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_qhp_pcie_serdes_tbl),
++      .tx_tbl                 = sdm845_qhp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_qhp_pcie_tx_tbl),
++      .rx_tbl                 = sdm845_qhp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_qhp_pcie_rx_tbl),
++      .pcs_tbl                = sdm845_qhp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_qhp_pcie_pcs_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_qhp_pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sm8250_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
++      .serdes_tbl_sec         = sm8250_qmp_gen3x1_pcie_serdes_tbl,
++      .serdes_tbl_num_sec     = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_serdes_tbl),
++      .tx_tbl                 = sm8250_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sm8250_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
++      .rx_tbl_sec             = sm8250_qmp_gen3x1_pcie_rx_tbl,
++      .rx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_rx_tbl),
++      .pcs_tbl                = sm8250_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
++      .pcs_tbl_sec            = sm8250_qmp_gen3x1_pcie_pcs_tbl,
++      .pcs_tbl_num_sec                = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8250_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
++      .pcs_misc_tbl_sec               = sm8250_qmp_gen3x1_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num_sec   = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sm8250_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sm8250_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
++      .tx_tbl_sec             = sm8250_qmp_gen3x2_pcie_tx_tbl,
++      .tx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_tx_tbl),
++      .rx_tbl                 = sm8250_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
++      .rx_tbl_sec             = sm8250_qmp_gen3x2_pcie_rx_tbl,
++      .rx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_rx_tbl),
++      .pcs_tbl                = sm8250_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
++      .pcs_tbl_sec            = sm8250_qmp_gen3x2_pcie_pcs_tbl,
++      .pcs_tbl_num_sec                = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8250_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
++      .pcs_misc_tbl_sec               = sm8250_qmp_gen3x2_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num_sec   = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc7180_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v3_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v3_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v3_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v3_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v3_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v3_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v3_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v3_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v3_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sc7180_usb3dpphy_cfg = {
++      .usb_cfg                = &sc7180_usb3phy_cfg,
++      .dp_cfg                 = &sc7180_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sdm845_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
++      .tx_tbl                 = sdm845_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
++      .rx_tbl                 = sdm845_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
++      .pcs_tbl                = sdm845_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm6115_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm6115_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
++      .rx_tbl                 = sm6115_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
++      .pcs_tbl                = sm6115_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm6115_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++
++      .is_dual_lane_phy       = false,
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8998_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8998_pcie_serdes_tbl),
++      .tx_tbl                 = msm8998_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8998_pcie_tx_tbl),
++      .rx_tbl                 = msm8998_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8998_pcie_rx_tbl),
++      .pcs_tbl                = msm8998_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8998_pcie_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++};
++
++static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8998_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl),
++      .tx_tbl                 = msm8998_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8998_usb3_tx_tbl),
++      .rx_tbl                 = msm8998_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
++      .pcs_tbl                = msm8998_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8150_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8150_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8150_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8150_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8150_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_usb3_tx_tbl),
++      .rx_tbl                 = sm8150_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_usb3_rx_tbl),
++      .pcs_tbl                = sm8150_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sc8180x_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sc8180x_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sc8180x_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sc8180x_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sc8180x_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sc8180x_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sc8180x_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v4_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v4_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v4_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v4_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v4_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v4_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sc8180x_usb3dpphy_cfg = {
++      .usb_cfg                = &sm8150_usb3phy_cfg,
++      .dp_cfg                 = &sc8180x_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8150_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8150_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8150_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8250_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_usb3_tx_tbl),
++      .rx_tbl                 = sm8250_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_usb3_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_sm8250_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8250_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8250_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8250_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v4_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v4_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v4_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v4_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v4_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v4_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sm8250_usb3dpphy_cfg = {
++      .usb_cfg                = &sm8250_usb3phy_cfg,
++      .dp_cfg                 = &sm8250_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sdx55_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx55_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sdx55_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx55_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_sdx55_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sdx55_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdx55_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sdx55_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx55_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sdx55_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx55_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sdx55_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdx55_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sdx55_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sdx55_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS_4_20,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sdx65_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx65_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sdx65_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx65_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_sdx55_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8350_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8350_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8350_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8350_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8350_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8350_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_usb3_tx_tbl),
++      .rx_tbl                 = sm8350_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_usb3_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_sm8250_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8350_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8350_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8350_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8350_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8350_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8350_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8350_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
++      .clk_list               = sm8450_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sm8450_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8450_qmp_gen3x1_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sm8450_qmp_gen3x1_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_serdes_tbl),
++      .tx_tbl                 = sm8450_qmp_gen3x1_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_tx_tbl),
++      .rx_tbl                 = sm8450_qmp_gen3x1_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_rx_tbl),
++      .pcs_tbl                = sm8450_qmp_gen3x1_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8450_qmp_gen3x1_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8450_qmp_gen4x2_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sm8450_qmp_gen4x2_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_serdes_tbl),
++      .tx_tbl                 = sm8450_qmp_gen4x2_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_tx_tbl),
++      .rx_tbl                 = sm8450_qmp_gen4x2_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_rx_tbl),
++      .pcs_tbl                = sm8450_qmp_gen4x2_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8450_qmp_gen4x2_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS_4_20,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qcm2290_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
++      .tx_tbl                 = qcm2290_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_tx_tbl),
++      .rx_tbl                 = qcm2290_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_rx_tbl),
++      .pcs_tbl                = qcm2290_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
++      .clk_list               = qcm2290_usb3phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qcm2290_usb3phy_clk_l),
++      .reset_list             = qcm2290_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(qcm2290_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qcm2290_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static void qcom_qmp_phy_configure_lane(void __iomem *base,
++                                      const unsigned int *regs,
++                                      const struct qmp_phy_init_tbl tbl[],
++                                      int num,
++                                      u8 lane_mask)
++{
++      int i;
++      const struct qmp_phy_init_tbl *t = tbl;
++
++      if (!t)
++              return;
++
++      for (i = 0; i < num; i++, t++) {
++              if (!(t->lane_mask & lane_mask))
++                      continue;
++
++              if (t->in_layout)
++                      writel(t->val, base + regs[t->offset]);
++              else
++                      writel(t->val, base + t->offset);
++      }
++}
++
++static void qcom_qmp_phy_configure(void __iomem *base,
++                                 const unsigned int *regs,
++                                 const struct qmp_phy_init_tbl tbl[],
++                                 int num)
++{
++      qcom_qmp_phy_configure_lane(base, regs, tbl, num, 0xff);
++}
++
++static int qcom_qmp_phy_serdes_init(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
++      int serdes_tbl_num = cfg->serdes_tbl_num;
++      int ret;
++
++      qcom_qmp_phy_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num);
++      if (cfg->serdes_tbl_sec)
++              qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl_sec,
++                                     cfg->serdes_tbl_num_sec);
++
++      if (cfg->type == PHY_TYPE_DP) {
++              switch (dp_opts->link_rate) {
++              case 1620:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_rbr,
++                                             cfg->serdes_tbl_rbr_num);
++                      break;
++              case 2700:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr,
++                                             cfg->serdes_tbl_hbr_num);
++                      break;
++              case 5400:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr2,
++                                             cfg->serdes_tbl_hbr2_num);
++                      break;
++              case 8100:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr3,
++                                             cfg->serdes_tbl_hbr3_num);
++                      break;
++              default:
++                      /* Other link rates aren't supported */
++                      return -EINVAL;
++              }
++      }
++
++
++      if (cfg->has_phy_com_ctrl) {
++              void __iomem *status;
++              unsigned int mask, val;
++
++              qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET], SW_RESET);
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
++                           SERDES_START | PCS_START);
++
++              status = serdes + cfg->regs[QPHY_COM_PCS_READY_STATUS];
++              mask = cfg->mask_com_pcs_ready;
++
++              ret = readl_poll_timeout(status, val, (val & mask), 10,
++                                       PHY_INIT_COMPLETE_TIMEOUT);
++              if (ret) {
++                      dev_err(qmp->dev,
++                              "phy common block init timed-out\n");
++                      return ret;
++              }
++      }
++
++      return 0;
++}
++
++static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy)
++{
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      /* Turn on BIAS current for PHY/PLL */
++      writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX |
++             QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL,
++             qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_LANE_0_1_PWRDN |
++             DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN |
++             DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(QSERDES_V3_COM_BIAS_EN |
++             QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN |
++             QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL |
++             QSERDES_V3_COM_CLKBUF_RX_DRIVE_L,
++             qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0x24, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
++      writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
++      writel(0xbb, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
++      qphy->dp_aux_cfg = 0;
++
++      writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
++             PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
++             PHY_AUX_REQ_ERR_MASK,
++             qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
++}
++
++static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = {
++      { 0x00, 0x0c, 0x15, 0x1a },
++      { 0x02, 0x0e, 0x16, 0xff },
++      { 0x02, 0x11, 0xff, 0xff },
++      { 0x04, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_voltage_swing_hbr3_hbr2[4][4] = {
++      { 0x02, 0x12, 0x16, 0x1a },
++      { 0x09, 0x19, 0x1f, 0xff },
++      { 0x10, 0x1f, 0xff, 0xff },
++      { 0x1f, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = {
++      { 0x00, 0x0c, 0x14, 0x19 },
++      { 0x00, 0x0b, 0x12, 0xff },
++      { 0x00, 0x0b, 0xff, 0xff },
++      { 0x04, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
++      { 0x08, 0x0f, 0x16, 0x1f },
++      { 0x11, 0x1e, 0x1f, 0xff },
++      { 0x19, 0x1f, 0xff, 0xff },
++      { 0x1f, 0xff, 0xff, 0xff }
++};
++
++static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy,
++              unsigned int drv_lvl_reg, unsigned int emp_post_reg)
++{
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      unsigned int v_level = 0, p_level = 0;
++      u8 voltage_swing_cfg, pre_emphasis_cfg;
++      int i;
++
++      for (i = 0; i < dp_opts->lanes; i++) {
++              v_level = max(v_level, dp_opts->voltage[i]);
++              p_level = max(p_level, dp_opts->pre[i]);
++      }
++
++      if (dp_opts->link_rate <= 2700) {
++              voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
++              pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
++      } else {
++              voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr3_hbr2[v_level][p_level];
++              pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr3_hbr2[v_level][p_level];
++      }
++
++      /* TODO: Move check to config check */
++      if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
++              return -EINVAL;
++
++      /* Enable MUX to use Cursor values from these registers */
++      voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
++      pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
++
++      writel(voltage_swing_cfg, qphy->tx + drv_lvl_reg);
++      writel(pre_emphasis_cfg, qphy->tx + emp_post_reg);
++      writel(voltage_swing_cfg, qphy->tx2 + drv_lvl_reg);
++      writel(pre_emphasis_cfg, qphy->tx2 + emp_post_reg);
++
++      return 0;
++}
++
++static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)
++{
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 bias_en, drvr_en;
++
++      if (qcom_qmp_phy_configure_dp_swing(qphy,
++                              QSERDES_V3_TX_TX_DRV_LVL,
++                              QSERDES_V3_TX_TX_EMP_POST1_LVL) < 0)
++              return;
++
++      if (dp_opts->lanes == 1) {
++              bias_en = 0x3e;
++              drvr_en = 0x13;
++      } else {
++              bias_en = 0x3f;
++              drvr_en = 0x10;
++      }
++
++      writel(drvr_en, qphy->tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
++      writel(bias_en, qphy->tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
++      writel(drvr_en, qphy->tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
++      writel(bias_en, qphy->tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
++}
++
++static bool qcom_qmp_phy_configure_dp_mode(struct qmp_phy *qphy)
++{
++      u32 val;
++      bool reverse = false;
++
++      val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++            DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN;
++
++      /*
++       * TODO: Assume orientation is CC1 for now and two lanes, need to
++       * use type-c connector to understand orientation and lanes.
++       *
++       * Otherwise val changes to be like below if this code understood
++       * the orientation of the type-c cable.
++       *
++       * if (lane_cnt == 4 || orientation == ORIENTATION_CC2)
++       *      val |= DP_PHY_PD_CTL_LANE_0_1_PWRDN;
++       * if (lane_cnt == 4 || orientation == ORIENTATION_CC1)
++       *      val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
++       * if (orientation == ORIENTATION_CC2)
++       *      writel(0x4c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
++       */
++      val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
++      writel(val, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(0x5c, qphy->pcs + QSERDES_DP_PHY_MODE);
++
++      return reverse;
++}
++
++static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 phy_vco_div, status;
++      unsigned long pixel_freq;
++
++      qcom_qmp_phy_configure_dp_mode(qphy);
++
++      writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
++      writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              phy_vco_div = 0x1;
++              pixel_freq = 1620000000UL / 2;
++              break;
++      case 2700:
++              phy_vco_div = 0x1;
++              pixel_freq = 2700000000UL / 2;
++              break;
++      case 5400:
++              phy_vco_div = 0x2;
++              pixel_freq = 5400000000UL / 4;
++              break;
++      case 8100:
++              phy_vco_div = 0x0;
++              pixel_freq = 8100000000UL / 6;
++              break;
++      default:
++              /* Other link rates aren't supported */
++              return -EINVAL;
++      }
++      writel(phy_vco_div, qphy->pcs + QSERDES_V3_DP_PHY_VCO_DIV);
++
++      clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
++      clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
++
++      writel(0x04, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      writel(0x20, qphy->serdes + QSERDES_V3_COM_RESETSM_CNTRL);
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V3_COM_C_READY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
++      udelay(2000);
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      return readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000);
++}
++
++/*
++ * We need to calibrate the aux setting here as many times
++ * as the caller tries
++ */
++static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy)
++{
++      static const u8 cfg1_settings[] = { 0x13, 0x23, 0x1d };
++      u8 val;
++
++      qphy->dp_aux_cfg++;
++      qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
++      val = cfg1_settings[qphy->dp_aux_cfg];
++
++      writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++
++      return 0;
++}
++
++static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy)
++{
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      /* Turn on BIAS current for PHY/PLL */
++      writel(0x17, qphy->serdes + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
++      writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
++      writel(0xb7, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
++      qphy->dp_aux_cfg = 0;
++
++      writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
++             PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
++             PHY_AUX_REQ_ERR_MASK,
++             qphy->pcs + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
++}
++
++static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy)
++{
++      /* Program default values before writing proper values */
++      writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
++      writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
++
++      writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++      writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++
++      qcom_qmp_phy_configure_dp_swing(qphy,
++                      QSERDES_V4_TX_TX_DRV_LVL,
++                      QSERDES_V4_TX_TX_EMP_POST1_LVL);
++}
++
++static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 phy_vco_div, status;
++      unsigned long pixel_freq;
++      u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
++      bool reverse;
++
++      writel(0x0f, qphy->pcs + QSERDES_V4_DP_PHY_CFG_1);
++
++      reverse = qcom_qmp_phy_configure_dp_mode(qphy);
++
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++
++      writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL);
++      writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL);
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              phy_vco_div = 0x1;
++              pixel_freq = 1620000000UL / 2;
++              break;
++      case 2700:
++              phy_vco_div = 0x1;
++              pixel_freq = 2700000000UL / 2;
++              break;
++      case 5400:
++              phy_vco_div = 0x2;
++              pixel_freq = 5400000000UL / 4;
++              break;
++      case 8100:
++              phy_vco_div = 0x0;
++              pixel_freq = 8100000000UL / 6;
++              break;
++      default:
++              /* Other link rates aren't supported */
++              return -EINVAL;
++      }
++      writel(phy_vco_div, qphy->pcs + QSERDES_V4_DP_PHY_VCO_DIV);
++
++      clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
++      clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
++
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      writel(0x20, qphy->serdes + QSERDES_V4_COM_RESETSM_CNTRL);
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_C_READY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      /*
++       * At least for 7nm DP PHY this has to be done after enabling link
++       * clock.
++       */
++
++      if (dp_opts->lanes == 1) {
++              bias0_en = reverse ? 0x3e : 0x15;
++              bias1_en = reverse ? 0x15 : 0x3e;
++              drvr0_en = reverse ? 0x13 : 0x10;
++              drvr1_en = reverse ? 0x10 : 0x13;
++      } else if (dp_opts->lanes == 2) {
++              bias0_en = reverse ? 0x3f : 0x15;
++              bias1_en = reverse ? 0x15 : 0x3f;
++              drvr0_en = 0x10;
++              drvr1_en = 0x10;
++      } else {
++              bias0_en = 0x3f;
++              bias1_en = 0x3f;
++              drvr0_en = 0x10;
++              drvr1_en = 0x10;
++      }
++
++      writel(drvr0_en, qphy->tx + QSERDES_V4_TX_HIGHZ_DRVR_EN);
++      writel(bias0_en, qphy->tx + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
++      writel(drvr1_en, qphy->tx2 + QSERDES_V4_TX_HIGHZ_DRVR_EN);
++      writel(bias1_en, qphy->tx2 + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
++
++      writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
++      udelay(2000);
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x0a, qphy->tx + QSERDES_V4_TX_TX_POL_INV);
++      writel(0x0a, qphy->tx2 + QSERDES_V4_TX_TX_POL_INV);
++
++      writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
++      writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
++
++      writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++      writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++
++      return 0;
++}
++
++/*
++ * We need to calibrate the aux setting here as many times
++ * as the caller tries
++ */
++static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy)
++{
++      static const u8 cfg1_settings[] = { 0x20, 0x13, 0x23, 0x1d };
++      u8 val;
++
++      qphy->dp_aux_cfg++;
++      qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
++      val = cfg1_settings[qphy->dp_aux_cfg];
++
++      writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++
++      return 0;
++}
++
++static int qcom_qmp_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
++{
++      const struct phy_configure_opts_dp *dp_opts = &opts->dp;
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      memcpy(&qphy->dp_opts, dp_opts, sizeof(*dp_opts));
++      if (qphy->dp_opts.set_voltages) {
++              cfg->configure_dp_tx(qphy);
++              qphy->dp_opts.set_voltages = 0;
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_dp_phy_calibrate(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      if (cfg->calibrate_dp_phy)
++              return cfg->calibrate_dp_phy(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_com_init(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *dp_com = qmp->dp_com;
++      int ret, i;
++
++      mutex_lock(&qmp->phy_mutex);
++      if (qmp->init_count++) {
++              mutex_unlock(&qmp->phy_mutex);
++              return 0;
++      }
++
++      /* turn on regulator supplies */
++      ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
++      if (ret) {
++              dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
++              goto err_unlock;
++      }
++
++      for (i = 0; i < cfg->num_resets; i++) {
++              ret = reset_control_assert(qmp->resets[i]);
++              if (ret) {
++                      dev_err(qmp->dev, "%s reset assert failed\n",
++                              cfg->reset_list[i]);
++                      goto err_disable_regulators;
++              }
++      }
++
++      for (i = cfg->num_resets - 1; i >= 0; i--) {
++              ret = reset_control_deassert(qmp->resets[i]);
++              if (ret) {
++                      dev_err(qmp->dev, "%s reset deassert failed\n",
++                              qphy->cfg->reset_list[i]);
++                      goto err_assert_reset;
++              }
++      }
++
++      ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
++      if (ret)
++              goto err_assert_reset;
++
++      if (cfg->has_phy_dp_com_ctrl) {
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_POWER_DOWN_CTRL,
++                           SW_PWRDN);
++              /* override hardware control for reset of qmp phy */
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
++                           SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
++                           SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
++
++              /* Default type-c orientation, i.e CC1 */
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_TYPEC_CTRL, 0x02);
++
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_PHY_MODE_CTRL,
++                           USB3_MODE | DP_MODE);
++
++              /* bring both QMP USB and QMP DP PHYs PCS block out of reset */
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
++                           SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
++                           SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
++
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_SWI_CTRL, 0x03);
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
++      }
++
++      if (cfg->has_phy_com_ctrl) {
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
++                           SW_PWRDN);
++      } else {
++              if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
++                      qphy_setbits(pcs,
++                                      cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++                                      cfg->pwrdn_ctrl);
++              else
++                      qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL,
++                                      cfg->pwrdn_ctrl);
++      }
++
++      mutex_unlock(&qmp->phy_mutex);
++
++      return 0;
++
++err_assert_reset:
++      while (++i < cfg->num_resets)
++              reset_control_assert(qmp->resets[i]);
++err_disable_regulators:
++      regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
++err_unlock:
++      mutex_unlock(&qmp->phy_mutex);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_com_exit(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      int i = cfg->num_resets;
++
++      mutex_lock(&qmp->phy_mutex);
++      if (--qmp->init_count) {
++              mutex_unlock(&qmp->phy_mutex);
++              return 0;
++      }
++
++      reset_control_assert(qmp->ufs_reset);
++      if (cfg->has_phy_com_ctrl) {
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
++                           SERDES_START | PCS_START);
++              qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET],
++                           SW_RESET);
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
++                           SW_PWRDN);
++      }
++
++      while (--i >= 0)
++              reset_control_assert(qmp->resets[i]);
++
++      clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++
++      regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
++
++      mutex_unlock(&qmp->phy_mutex);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_init(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      int ret;
++      dev_vdbg(qmp->dev, "Initializing QMP phy\n");
++
++      if (cfg->no_pcs_sw_reset) {
++              /*
++               * Get UFS reset, which is delayed until now to avoid a
++               * circular dependency where UFS needs its PHY, but the PHY
++               * needs this UFS reset.
++               */
++              if (!qmp->ufs_reset) {
++                      qmp->ufs_reset =
++                              devm_reset_control_get_exclusive(qmp->dev,
++                                                               "ufsphy");
++
++                      if (IS_ERR(qmp->ufs_reset)) {
++                              ret = PTR_ERR(qmp->ufs_reset);
++                              dev_err(qmp->dev,
++                                      "failed to get UFS reset: %d\n",
++                                      ret);
++
++                              qmp->ufs_reset = NULL;
++                              return ret;
++                      }
++              }
++
++              ret = reset_control_assert(qmp->ufs_reset);
++              if (ret)
++                      return ret;
++      }
++
++      ret = qcom_qmp_phy_com_init(qphy);
++      if (ret)
++              return ret;
++
++      if (cfg->type == PHY_TYPE_DP)
++              cfg->dp_aux_init(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_power_on(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *tx = qphy->tx;
++      void __iomem *rx = qphy->rx;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++      void __iomem *status;
++      unsigned int mask, val, ready;
++      int ret;
++
++      qcom_qmp_phy_serdes_init(qphy);
++
++      if (cfg->has_lane_rst) {
++              ret = reset_control_deassert(qphy->lane_rst);
++              if (ret) {
++                      dev_err(qmp->dev, "lane%d reset deassert failed\n",
++                              qphy->index);
++                      return ret;
++              }
++      }
++
++      ret = clk_prepare_enable(qphy->pipe_clk);
++      if (ret) {
++              dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
++              goto err_reset_lane;
++      }
++
++      /* Tx, Rx, and PCS configurations */
++      qcom_qmp_phy_configure_lane(tx, cfg->regs,
++                                  cfg->tx_tbl, cfg->tx_tbl_num, 1);
++      if (cfg->tx_tbl_sec)
++              qcom_qmp_phy_configure_lane(tx, cfg->regs, cfg->tx_tbl_sec,
++                                          cfg->tx_tbl_num_sec, 1);
++
++      /* Configuration for other LANE for USB-DP combo PHY */
++      if (cfg->is_dual_lane_phy) {
++              qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
++                                          cfg->tx_tbl, cfg->tx_tbl_num, 2);
++              if (cfg->tx_tbl_sec)
++                      qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
++                                                  cfg->tx_tbl_sec,
++                                                  cfg->tx_tbl_num_sec, 2);
++      }
++
++      /* Configure special DP tx tunings */
++      if (cfg->type == PHY_TYPE_DP)
++              cfg->configure_dp_tx(qphy);
++
++      qcom_qmp_phy_configure_lane(rx, cfg->regs,
++                                  cfg->rx_tbl, cfg->rx_tbl_num, 1);
++      if (cfg->rx_tbl_sec)
++              qcom_qmp_phy_configure_lane(rx, cfg->regs,
++                                          cfg->rx_tbl_sec, cfg->rx_tbl_num_sec, 1);
++
++      if (cfg->is_dual_lane_phy) {
++              qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
++                                          cfg->rx_tbl, cfg->rx_tbl_num, 2);
++              if (cfg->rx_tbl_sec)
++                      qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
++                                                  cfg->rx_tbl_sec,
++                                                  cfg->rx_tbl_num_sec, 2);
++      }
++
++      /* Configure link rate, swing, etc. */
++      if (cfg->type == PHY_TYPE_DP) {
++              cfg->configure_dp_phy(qphy);
++      } else {
++              qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
++              if (cfg->pcs_tbl_sec)
++                      qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl_sec,
++                                             cfg->pcs_tbl_num_sec);
++      }
++
++      ret = reset_control_deassert(qmp->ufs_reset);
++      if (ret)
++              goto err_disable_pipe_clk;
++
++      qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl,
++                             cfg->pcs_misc_tbl_num);
++      if (cfg->pcs_misc_tbl_sec)
++              qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl_sec,
++                                     cfg->pcs_misc_tbl_num_sec);
++
++      /*
++       * Pull out PHY from POWER DOWN state.
++       * This is active low enable signal to power-down PHY.
++       */
++      if(cfg->type == PHY_TYPE_PCIE)
++              qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
++
++      if (cfg->has_pwrdn_delay)
++              usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
++
++      if (cfg->type != PHY_TYPE_DP) {
++              /* Pull PHY out of reset state */
++              if (!cfg->no_pcs_sw_reset)
++                      qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
++              /* start SerDes and Phy-Coding-Sublayer */
++              qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
++
++              if (cfg->type == PHY_TYPE_UFS) {
++                      status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
++                      mask = PCS_READY;
++                      ready = PCS_READY;
++              } else {
++                      status = pcs + cfg->regs[QPHY_PCS_STATUS];
++                      mask = cfg->phy_status;
++                      ready = 0;
++              }
++
++              ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
++                                       PHY_INIT_COMPLETE_TIMEOUT);
++              if (ret) {
++                      dev_err(qmp->dev, "phy initialization timed-out\n");
++                      goto err_disable_pipe_clk;
++              }
++      }
++      return 0;
++
++err_disable_pipe_clk:
++      clk_disable_unprepare(qphy->pipe_clk);
++err_reset_lane:
++      if (cfg->has_lane_rst)
++              reset_control_assert(qphy->lane_rst);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_power_off(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      clk_disable_unprepare(qphy->pipe_clk);
++
++      if (cfg->type == PHY_TYPE_DP) {
++              /* Assert DP PHY power down */
++              writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++      } else {
++              /* PHY reset */
++              if (!cfg->no_pcs_sw_reset)
++                      qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
++
++              /* stop SerDes and Phy-Coding-Sublayer */
++              qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
++
++              /* Put PHY into POWER DOWN state: active low */
++              if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) {
++                      qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++                                   cfg->pwrdn_ctrl);
++              } else {
++                      qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL,
++                                      cfg->pwrdn_ctrl);
++              }
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_phy_exit(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      if (cfg->has_lane_rst)
++              reset_control_assert(qphy->lane_rst);
++
++      qcom_qmp_phy_com_exit(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_enable(struct phy *phy)
++{
++      int ret;
++
++      ret = qcom_qmp_phy_init(phy);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_power_on(phy);
++      if (ret)
++              qcom_qmp_phy_exit(phy);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_disable(struct phy *phy)
++{
++      int ret;
++
++      ret = qcom_qmp_phy_power_off(phy);
++      if (ret)
++              return ret;
++      return qcom_qmp_phy_exit(phy);
++}
++
++static int qcom_qmp_phy_set_mode(struct phy *phy,
++                               enum phy_mode mode, int submode)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++
++      qphy->mode = mode;
++
++      return 0;
++}
++
++static void qcom_qmp_phy_enable_autonomous_mode(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++      u32 intr_mask;
++
++      if (qphy->mode == PHY_MODE_USB_HOST_SS ||
++          qphy->mode == PHY_MODE_USB_DEVICE_SS)
++              intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
++      else
++              intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
++
++      /* Clear any pending interrupts status */
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++      /* Writing 1 followed by 0 clears the interrupt */
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
++                   ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);
++
++      /* Enable required PHY autonomous mode interrupts */
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
++
++      /* Enable i/o clamp_n for autonomous mode */
++      if (pcs_misc)
++              qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
++}
++
++static void qcom_qmp_phy_disable_autonomous_mode(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++
++      /* Disable i/o clamp_n on resume for normal mode */
++      if (pcs_misc)
++              qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
++
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
++                   ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
++
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++      /* Writing 1 followed by 0 clears the interrupt */
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++}
++
++static int __maybe_unused qcom_qmp_phy_runtime_suspend(struct device *dev)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct qmp_phy *qphy = qmp->phys[0];
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qphy->mode);
++
++      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
++      if (cfg->type != PHY_TYPE_USB3)
++              return 0;
++
++      if (!qmp->init_count) {
++              dev_vdbg(dev, "PHY not initialized, bailing out\n");
++              return 0;
++      }
++
++      qcom_qmp_phy_enable_autonomous_mode(qphy);
++
++      clk_disable_unprepare(qphy->pipe_clk);
++      clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++
++      return 0;
++}
++
++static int __maybe_unused qcom_qmp_phy_runtime_resume(struct device *dev)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct qmp_phy *qphy = qmp->phys[0];
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      int ret = 0;
++
++      dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qphy->mode);
++
++      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
++      if (cfg->type != PHY_TYPE_USB3)
++              return 0;
++
++      if (!qmp->init_count) {
++              dev_vdbg(dev, "PHY not initialized, bailing out\n");
++              return 0;
++      }
++
++      ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
++      if (ret)
++              return ret;
++
++      ret = clk_prepare_enable(qphy->pipe_clk);
++      if (ret) {
++              dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
++              clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++              return ret;
++      }
++
++      qcom_qmp_phy_disable_autonomous_mode(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int num = cfg->num_vregs;
++      int i;
++
++      qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
++      if (!qmp->vregs)
++              return -ENOMEM;
++
++      for (i = 0; i < num; i++)
++              qmp->vregs[i].supply = cfg->vreg_list[i];
++
++      return devm_regulator_bulk_get(dev, num, qmp->vregs);
++}
++
++static int qcom_qmp_phy_reset_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int i;
++
++      qmp->resets = devm_kcalloc(dev, cfg->num_resets,
++                                 sizeof(*qmp->resets), GFP_KERNEL);
++      if (!qmp->resets)
++              return -ENOMEM;
++
++      for (i = 0; i < cfg->num_resets; i++) {
++              struct reset_control *rst;
++              const char *name = cfg->reset_list[i];
++
++              rst = devm_reset_control_get_exclusive(dev, name);
++              if (IS_ERR(rst)) {
++                      dev_err(dev, "failed to get %s reset\n", name);
++                      return PTR_ERR(rst);
++              }
++              qmp->resets[i] = rst;
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_phy_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int num = cfg->num_clks;
++      int i;
++
++      qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
++      if (!qmp->clks)
++              return -ENOMEM;
++
++      for (i = 0; i < num; i++)
++              qmp->clks[i].id = cfg->clk_list[i];
++
++      return devm_clk_bulk_get(dev, num, qmp->clks);
++}
++
++static void phy_clk_release_provider(void *res)
++{
++      of_clk_del_provider(res);
++}
++
++/*
++ * Register a fixed rate pipe clock.
++ *
++ * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
++ * controls it. The <s>_pipe_clk coming out of the GCC is requested
++ * by the PHY driver for its operations.
++ * We register the <s>_pipe_clksrc here. The gcc driver takes care
++ * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
++ * Below picture shows this relationship.
++ *
++ *         +---------------+
++ *         |   PHY block   |<<---------------------------------------+
++ *         |               |                                         |
++ *         |   +-------+   |                   +-----+               |
++ *   I/P---^-->|  PLL  |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
++ *    clk  |   +-------+   |                   +-----+
++ *         +---------------+
++ */
++static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
++{
++      struct clk_fixed_rate *fixed;
++      struct clk_init_data init = { };
++      int ret;
++
++      ret = of_property_read_string(np, "clock-output-names", &init.name);
++      if (ret) {
++              dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
++              return ret;
++      }
++
++      fixed = devm_kzalloc(qmp->dev, sizeof(*fixed), GFP_KERNEL);
++      if (!fixed)
++              return -ENOMEM;
++
++      init.ops = &clk_fixed_rate_ops;
++
++      /* controllers using QMP phys use 125MHz pipe clock interface */
++      fixed->fixed_rate = 125000000;
++      fixed->hw.init = &init;
++
++      ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
++      if (ret)
++              return ret;
++
++      ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
++      if (ret)
++              return ret;
++
++      /*
++       * Roll a devm action because the clock provider is the child node, but
++       * the child node is not actually a device.
++       */
++      return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
++}
++
++/*
++ * Display Port PLL driver block diagram for branch clocks
++ *
++ *              +------------------------------+
++ *              |         DP_VCO_CLK           |
++ *              |                              |
++ *              |    +-------------------+     |
++ *              |    |   (DP PLL/VCO)    |     |
++ *              |    +---------+---------+     |
++ *              |              v               |
++ *              |   +----------+-----------+   |
++ *              |   | hsclk_divsel_clk_src |   |
++ *              |   +----------+-----------+   |
++ *              +------------------------------+
++ *                              |
++ *          +---------<---------v------------>----------+
++ *          |                                           |
++ * +--------v----------------+                          |
++ * |    dp_phy_pll_link_clk  |                          |
++ * |     link_clk            |                          |
++ * +--------+----------------+                          |
++ *          |                                           |
++ *          |                                           |
++ *          v                                           v
++ * Input to DISPCC block                                |
++ * for link clk, crypto clk                             |
++ * and interface clock                                  |
++ *                                                      |
++ *                                                      |
++ *      +--------<------------+-----------------+---<---+
++ *      |                     |                 |
++ * +----v---------+  +--------v-----+  +--------v------+
++ * | vco_divided  |  | vco_divided  |  | vco_divided   |
++ * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
++ * |              |  |              |  |               |
++ * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
++ * +-------+------+  +-----+--------+  +--------+------+
++ *         |                 |                  |
++ *         v---->----------v-------------<------v
++ *                         |
++ *              +----------+-----------------+
++ *              |   dp_phy_pll_vco_div_clk   |
++ *              +---------+------------------+
++ *                        |
++ *                        v
++ *              Input to DISPCC block
++ *              for DP pixel clock
++ *
++ */
++static int qcom_qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
++                                              struct clk_rate_request *req)
++{
++      switch (req->rate) {
++      case 1620000000UL / 2:
++      case 2700000000UL / 2:
++      /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
++              return 0;
++      default:
++              return -EINVAL;
++      }
++}
++
++static unsigned long
++qcom_qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
++{
++      const struct qmp_phy_dp_clks *dp_clks;
++      const struct qmp_phy *qphy;
++      const struct phy_configure_opts_dp *dp_opts;
++
++      dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_pixel_hw);
++      qphy = dp_clks->qphy;
++      dp_opts = &qphy->dp_opts;
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              return 1620000000UL / 2;
++      case 2700:
++              return 2700000000UL / 2;
++      case 5400:
++              return 5400000000UL / 4;
++      case 8100:
++              return 8100000000UL / 6;
++      default:
++              return 0;
++      }
++}
++
++static const struct clk_ops qcom_qmp_dp_pixel_clk_ops = {
++      .determine_rate = qcom_qmp_dp_pixel_clk_determine_rate,
++      .recalc_rate = qcom_qmp_dp_pixel_clk_recalc_rate,
++};
++
++static int qcom_qmp_dp_link_clk_determine_rate(struct clk_hw *hw,
++                                             struct clk_rate_request *req)
++{
++      switch (req->rate) {
++      case 162000000:
++      case 270000000:
++      case 540000000:
++      case 810000000:
++              return 0;
++      default:
++              return -EINVAL;
++      }
++}
++
++static unsigned long
++qcom_qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
++{
++      const struct qmp_phy_dp_clks *dp_clks;
++      const struct qmp_phy *qphy;
++      const struct phy_configure_opts_dp *dp_opts;
++
++      dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_link_hw);
++      qphy = dp_clks->qphy;
++      dp_opts = &qphy->dp_opts;
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++      case 2700:
++      case 5400:
++      case 8100:
++              return dp_opts->link_rate * 100000;
++      default:
++              return 0;
++      }
++}
++
++static const struct clk_ops qcom_qmp_dp_link_clk_ops = {
++      .determine_rate = qcom_qmp_dp_link_clk_determine_rate,
++      .recalc_rate = qcom_qmp_dp_link_clk_recalc_rate,
++};
++
++static struct clk_hw *
++qcom_qmp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *data)
++{
++      struct qmp_phy_dp_clks *dp_clks = data;
++      unsigned int idx = clkspec->args[0];
++
++      if (idx >= 2) {
++              pr_err("%s: invalid index %u\n", __func__, idx);
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (idx == 0)
++              return &dp_clks->dp_link_hw;
++
++      return &dp_clks->dp_pixel_hw;
++}
++
++static int phy_dp_clks_register(struct qcom_qmp *qmp, struct qmp_phy *qphy,
++                              struct device_node *np)
++{
++      struct clk_init_data init = { };
++      struct qmp_phy_dp_clks *dp_clks;
++      char name[64];
++      int ret;
++
++      dp_clks = devm_kzalloc(qmp->dev, sizeof(*dp_clks), GFP_KERNEL);
++      if (!dp_clks)
++              return -ENOMEM;
++
++      dp_clks->qphy = qphy;
++      qphy->dp_clks = dp_clks;
++
++      snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
++      init.ops = &qcom_qmp_dp_link_clk_ops;
++      init.name = name;
++      dp_clks->dp_link_hw.init = &init;
++      ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_link_hw);
++      if (ret)
++              return ret;
++
++      snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
++      init.ops = &qcom_qmp_dp_pixel_clk_ops;
++      init.name = name;
++      dp_clks->dp_pixel_hw.init = &init;
++      ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_pixel_hw);
++      if (ret)
++              return ret;
++
++      ret = of_clk_add_hw_provider(np, qcom_qmp_dp_clks_hw_get, dp_clks);
++      if (ret)
++              return ret;
++
++      /*
++       * Roll a devm action because the clock provider is the child node, but
++       * the child node is not actually a device.
++       */
++      return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
++}
++
++static const struct phy_ops qcom_qmp_phy_gen_ops = {
++      .init           = qcom_qmp_phy_enable,
++      .exit           = qcom_qmp_phy_disable,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static const struct phy_ops qcom_qmp_phy_dp_ops = {
++      .init           = qcom_qmp_phy_init,
++      .configure      = qcom_qmp_dp_phy_configure,
++      .power_on       = qcom_qmp_phy_power_on,
++      .calibrate      = qcom_qmp_dp_phy_calibrate,
++      .power_off      = qcom_qmp_phy_power_off,
++      .exit           = qcom_qmp_phy_exit,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static const struct phy_ops qcom_qmp_pcie_ufs_ops = {
++      .power_on       = qcom_qmp_phy_enable,
++      .power_off      = qcom_qmp_phy_disable,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static void qcom_qmp_reset_control_put(void *data)
++{
++      reset_control_put(data);
++}
++
++static
++int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id,
++                      void __iomem *serdes, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct phy *generic_phy;
++      struct qmp_phy *qphy;
++      const struct phy_ops *ops;
++      char prop_name[MAX_PROP_NAME];
++      int ret;
++
++      qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
++      if (!qphy)
++              return -ENOMEM;
++
++      qphy->cfg = cfg;
++      qphy->serdes = serdes;
++      /*
++       * Get memory resources for each phy lane:
++       * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
++       * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
++       * For single lane PHYs: pcs_misc (optional) -> 3.
++       */
++      qphy->tx = of_iomap(np, 0);
++      if (!qphy->tx)
++              return -ENOMEM;
++
++      qphy->rx = of_iomap(np, 1);
++      if (!qphy->rx)
++              return -ENOMEM;
++
++      qphy->pcs = of_iomap(np, 2);
++      if (!qphy->pcs)
++              return -ENOMEM;
++
++      /*
++       * If this is a dual-lane PHY, then there should be registers for the
++       * second lane. Some old device trees did not specify this, so fall
++       * back to old legacy behavior of assuming they can be reached at an
++       * offset from the first lane.
++       */
++      if (cfg->is_dual_lane_phy) {
++              qphy->tx2 = of_iomap(np, 3);
++              qphy->rx2 = of_iomap(np, 4);
++              if (!qphy->tx2 || !qphy->rx2) {
++                      dev_warn(dev,
++                               "Underspecified device tree, falling back to legacy register regions\n");
++
++                      /* In the old version, pcs_misc is at index 3. */
++                      qphy->pcs_misc = qphy->tx2;
++                      qphy->tx2 = qphy->tx + QMP_PHY_LEGACY_LANE_STRIDE;
++                      qphy->rx2 = qphy->rx + QMP_PHY_LEGACY_LANE_STRIDE;
++
++              } else {
++                      qphy->pcs_misc = of_iomap(np, 5);
++              }
++
++      } else {
++              qphy->pcs_misc = of_iomap(np, 3);
++      }
++
++      if (!qphy->pcs_misc)
++              dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
++
++      /*
++       * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3
++       * based phys, so they essentially have pipe clock. So,
++       * we return error in case phy is USB3 or PIPE type.
++       * Otherwise, we initialize pipe clock to NULL for
++       * all phys that don't need this.
++       */
++      snprintf(prop_name, sizeof(prop_name), "pipe%d", id);
++      qphy->pipe_clk = devm_get_clk_from_child(dev, np, prop_name);
++      if (IS_ERR(qphy->pipe_clk)) {
++              if (cfg->type == PHY_TYPE_PCIE ||
++                  cfg->type == PHY_TYPE_USB3) {
++                      ret = PTR_ERR(qphy->pipe_clk);
++                      if (ret != -EPROBE_DEFER)
++                              dev_err(dev,
++                                      "failed to get lane%d pipe_clk, %d\n",
++                                      id, ret);
++                      return ret;
++              }
++              qphy->pipe_clk = NULL;
++      }
++
++      /* Get lane reset, if any */
++      if (cfg->has_lane_rst) {
++              snprintf(prop_name, sizeof(prop_name), "lane%d", id);
++              qphy->lane_rst = of_reset_control_get_exclusive(np, prop_name);
++              if (IS_ERR(qphy->lane_rst)) {
++                      dev_err(dev, "failed to get lane%d reset\n", id);
++                      return PTR_ERR(qphy->lane_rst);
++              }
++              ret = devm_add_action_or_reset(dev, qcom_qmp_reset_control_put,
++                                             qphy->lane_rst);
++              if (ret)
++                      return ret;
++      }
++
++      if (cfg->type == PHY_TYPE_UFS || cfg->type == PHY_TYPE_PCIE)
++              ops = &qcom_qmp_pcie_ufs_ops;
++      else if (cfg->type == PHY_TYPE_DP)
++              ops = &qcom_qmp_phy_dp_ops;
++      else
++              ops = &qcom_qmp_phy_gen_ops;
++
++      generic_phy = devm_phy_create(dev, np, ops);
++      if (IS_ERR(generic_phy)) {
++              ret = PTR_ERR(generic_phy);
++              dev_err(dev, "failed to create qphy %d\n", ret);
++              return ret;
++      }
++
++      qphy->phy = generic_phy;
++      qphy->index = id;
++      qphy->qmp = qmp;
++      qmp->phys[id] = qphy;
++      phy_set_drvdata(generic_phy, qphy);
++
++      return 0;
++}
++
++static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
++      {
++              .compatible = "qcom,ipq8074-qmp-usb3-phy",
++              .data = &ipq8074_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-pcie-phy",
++              .data = &msm8996_pciephy_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-ufs-phy",
++              .data = &msm8996_ufs_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-usb3-phy",
++              .data = &msm8996_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-pcie-phy",
++              .data = &msm8998_pciephy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,ipq8074-qmp-pcie-phy",
++              .data = &ipq8074_pciephy_cfg,
++      }, {
++              .compatible = "qcom,ipq6018-qmp-pcie-phy",
++              .data = &ipq6018_pciephy_cfg,
++      }, {
++              .compatible = "qcom,ipq6018-qmp-usb3-phy",
++              .data = &ipq8074_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc7180-qmp-usb3-phy",
++              .data = &sc7180_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sc8180x-qmp-pcie-phy",
++              .data = &sc8180x_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sc8280xp-qmp-ufs-phy",
++              .data = &sm8350_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-usb3-phy",
++              .data = &sm8150_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sdm845-qhp-pcie-phy",
++              .data = &sdm845_qhp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-pcie-phy",
++              .data = &sdm845_qmp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-usb3-phy",
++              .data = &qmp_v3_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-usb3-uni-phy",
++              .data = &qmp_v3_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-usb3-phy",
++              .data = &msm8998_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm6115-qmp-ufs-phy",
++              .data = &sm6115_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm6350-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-usb3-phy",
++              .data = &sm8150_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-usb3-uni-phy",
++              .data = &sm8150_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-phy",
++              .data = &sm8250_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-uni-phy",
++              .data = &sm8250_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy",
++              .data = &sm8250_qmp_gen3x1_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-gen3x2-pcie-phy",
++              .data = &sm8250_qmp_gen3x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-ufs-phy",
++              .data = &sm8350_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-modem-pcie-phy",
++              .data = &sm8250_qmp_gen3x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdx55-qmp-pcie-phy",
++              .data = &sdx55_qmp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdx55-qmp-usb3-uni-phy",
++              .data = &sdx55_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sdx65-qmp-usb3-uni-phy",
++              .data = &sdx65_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-usb3-phy",
++              .data = &sm8350_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-usb3-uni-phy",
++              .data = &sm8350_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-gen3x1-pcie-phy",
++              .data = &sm8450_qmp_gen3x1_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-gen4x2-pcie-phy",
++              .data = &sm8450_qmp_gen4x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-ufs-phy",
++              .data = &sm8450_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-usb3-phy",
++              .data = &sm8350_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,qcm2290-qmp-usb3-phy",
++              .data = &qcm2290_usb3phy_cfg,
++      },
++      { },
++};
++MODULE_DEVICE_TABLE(of, qcom_qmp_phy_of_match_table);
++
++static const struct of_device_id qcom_qmp_combo_phy_of_match_table[] = {
++      {
++              .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
++              .data = &sc7180_usb3dpphy_cfg,
++      },
++      {
++              .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
++              .data = &sm8250_usb3dpphy_cfg,
++      },
++      {
++              .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
++              .data = &sc8180x_usb3dpphy_cfg,
++      },
++      { }
++};
++
++static const struct dev_pm_ops qcom_qmp_phy_pm_ops = {
++      SET_RUNTIME_PM_OPS(qcom_qmp_phy_runtime_suspend,
++                         qcom_qmp_phy_runtime_resume, NULL)
++};
++
++static int qcom_qmp_phy_probe(struct platform_device *pdev)
++{
++      struct qcom_qmp *qmp;
++      struct device *dev = &pdev->dev;
++      struct device_node *child;
++      struct phy_provider *phy_provider;
++      void __iomem *serdes;
++      void __iomem *usb_serdes;
++      void __iomem *dp_serdes = NULL;
++      const struct qmp_phy_combo_cfg *combo_cfg = NULL;
++      const struct qmp_phy_cfg *cfg = NULL;
++      const struct qmp_phy_cfg *usb_cfg = NULL;
++      const struct qmp_phy_cfg *dp_cfg = NULL;
++      int num, id, expected_phys;
++      int ret;
++
++      qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
++      if (!qmp)
++              return -ENOMEM;
++
++      qmp->dev = dev;
++      dev_set_drvdata(dev, qmp);
++
++      /* Get the specific init parameters of QMP phy */
++      cfg = of_device_get_match_data(dev);
++      if (!cfg) {
++              const struct of_device_id *match;
++
++              match = of_match_device(qcom_qmp_combo_phy_of_match_table, dev);
++              if (!match)
++                      return -EINVAL;
++
++              combo_cfg = match->data;
++              if (!combo_cfg)
++                      return -EINVAL;
++
++              usb_cfg = combo_cfg->usb_cfg;
++              cfg = usb_cfg; /* Setup clks and regulators */
++      }
++
++      /* per PHY serdes; usually located at base address */
++      usb_serdes = serdes = devm_platform_ioremap_resource(pdev, 0);
++      if (IS_ERR(serdes))
++              return PTR_ERR(serdes);
++
++      /* per PHY dp_com; if PHY has dp_com control block */
++      if (combo_cfg || cfg->has_phy_dp_com_ctrl) {
++              qmp->dp_com = devm_platform_ioremap_resource(pdev, 1);
++              if (IS_ERR(qmp->dp_com))
++                      return PTR_ERR(qmp->dp_com);
++      }
++
++      if (combo_cfg) {
++              /* Only two serdes for combo PHY */
++              dp_serdes = devm_platform_ioremap_resource(pdev, 2);
++              if (IS_ERR(dp_serdes))
++                      return PTR_ERR(dp_serdes);
++
++              dp_cfg = combo_cfg->dp_cfg;
++              expected_phys = 2;
++      } else {
++              expected_phys = cfg->nlanes;
++      }
++
++      mutex_init(&qmp->phy_mutex);
++
++      ret = qcom_qmp_phy_clk_init(dev, cfg);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_reset_init(dev, cfg);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_vreg_init(dev, cfg);
++      if (ret) {
++              if (ret != -EPROBE_DEFER)
++                      dev_err(dev, "failed to get regulator supplies: %d\n",
++                              ret);
++              return ret;
++      }
++
++      num = of_get_available_child_count(dev->of_node);
++      /* do we have a rogue child node ? */
++      if (num > expected_phys)
++              return -EINVAL;
++
++      qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
++      if (!qmp->phys)
++              return -ENOMEM;
++
++      pm_runtime_set_active(dev);
++      pm_runtime_enable(dev);
++      /*
++       * Prevent runtime pm from being ON by default. Users can enable
++       * it using power/control in sysfs.
++       */
++      pm_runtime_forbid(dev);
++
++      id = 0;
++      for_each_available_child_of_node(dev->of_node, child) {
++              if (of_node_name_eq(child, "dp-phy")) {
++                      cfg = dp_cfg;
++                      serdes = dp_serdes;
++              } else if (of_node_name_eq(child, "usb3-phy")) {
++                      cfg = usb_cfg;
++                      serdes = usb_serdes;
++              }
++
++              /* Create per-lane phy */
++              ret = qcom_qmp_phy_create(dev, child, id, serdes, cfg);
++              if (ret) {
++                      dev_err(dev, "failed to create lane%d phy, %d\n",
++                              id, ret);
++                      goto err_node_put;
++              }
++
++              /*
++               * Register the pipe clock provided by phy.
++               * See function description to see details of this pipe clock.
++               */
++              if (cfg->type == PHY_TYPE_USB3 || cfg->type == PHY_TYPE_PCIE) {
++                      ret = phy_pipe_clk_register(qmp, child);
++                      if (ret) {
++                              dev_err(qmp->dev,
++                                      "failed to register pipe clock source\n");
++                              goto err_node_put;
++                      }
++              } else if (cfg->type == PHY_TYPE_DP) {
++                      ret = phy_dp_clks_register(qmp, qmp->phys[id], child);
++                      if (ret) {
++                              dev_err(qmp->dev,
++                                      "failed to register DP clock source\n");
++                              goto err_node_put;
++                      }
++              }
++              id++;
++      }
++
++      phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
++      if (!IS_ERR(phy_provider))
++              dev_info(dev, "Registered Qcom-QMP phy\n");
++      else
++              pm_runtime_disable(dev);
++
++      return PTR_ERR_OR_ZERO(phy_provider);
++
++err_node_put:
++      pm_runtime_disable(dev);
++      of_node_put(child);
++      return ret;
++}
++
++static struct platform_driver qcom_qmp_phy_driver = {
++      .probe          = qcom_qmp_phy_probe,
++      .driver = {
++              .name   = "qcom-qmp-phy",
++              .pm     = &qcom_qmp_phy_pm_ops,
++              .of_match_table = qcom_qmp_phy_of_match_table,
++      },
++};
++
++module_platform_driver(qcom_qmp_phy_driver);
++
++MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
++MODULE_DESCRIPTION("Qualcomm QMP PHY driver");
++MODULE_LICENSE("GPL v2");
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+new file mode 100644
+index 000000000000..c7309e981bfb
+--- /dev/null
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+@@ -0,0 +1,6350 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++
++#include <dt-bindings/phy/phy.h>
++
++#include "phy-qcom-qmp.h"
++
++/* QPHY_SW_RESET bit */
++#define SW_RESET                              BIT(0)
++/* QPHY_POWER_DOWN_CONTROL */
++#define SW_PWRDN                              BIT(0)
++#define REFCLK_DRV_DSBL                               BIT(1)
++/* QPHY_START_CONTROL bits */
++#define SERDES_START                          BIT(0)
++#define PCS_START                             BIT(1)
++#define PLL_READY_GATE_EN                     BIT(3)
++/* QPHY_PCS_STATUS bit */
++#define PHYSTATUS                             BIT(6)
++#define PHYSTATUS_4_20                                BIT(7)
++/* QPHY_PCS_READY_STATUS & QPHY_COM_PCS_READY_STATUS bit */
++#define PCS_READY                             BIT(0)
++
++/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
++/* DP PHY soft reset */
++#define SW_DPPHY_RESET                                BIT(0)
++/* mux to select DP PHY reset control, 0:HW control, 1: software reset */
++#define SW_DPPHY_RESET_MUX                    BIT(1)
++/* USB3 PHY soft reset */
++#define SW_USB3PHY_RESET                      BIT(2)
++/* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
++#define SW_USB3PHY_RESET_MUX                  BIT(3)
++
++/* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
++#define USB3_MODE                             BIT(0) /* enables USB3 mode */
++#define DP_MODE                                       BIT(1) /* enables DP mode */
++
++/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
++#define ARCVR_DTCT_EN                         BIT(0)
++#define ALFPS_DTCT_EN                         BIT(1)
++#define ARCVR_DTCT_EVENT_SEL                  BIT(4)
++
++/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
++#define IRQ_CLEAR                             BIT(0)
++
++/* QPHY_PCS_LFPS_RXTERM_IRQ_STATUS register bits */
++#define RCVR_DETECT                           BIT(0)
++
++/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
++#define CLAMP_EN                              BIT(0) /* enables i/o clamp_n */
++
++#define PHY_INIT_COMPLETE_TIMEOUT             10000
++#define POWER_DOWN_DELAY_US_MIN                       10
++#define POWER_DOWN_DELAY_US_MAX                       11
++
++#define MAX_PROP_NAME                         32
++
++/* Define the assumed distance between lanes for underspecified device trees. */
++#define QMP_PHY_LEGACY_LANE_STRIDE            0x400
++
++struct qmp_phy_init_tbl {
++      unsigned int offset;
++      unsigned int val;
++      /*
++       * register part of layout ?
++       * if yes, then offset gives index in the reg-layout
++       */
++      bool in_layout;
++      /*
++       * mask of lanes for which this register is written
++       * for cases when second lane needs different values
++       */
++      u8 lane_mask;
++};
++
++#define QMP_PHY_INIT_CFG(o, v)                \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .lane_mask = 0xff,      \
++      }
++
++#define QMP_PHY_INIT_CFG_L(o, v)      \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .in_layout = true,      \
++              .lane_mask = 0xff,      \
++      }
++
++#define QMP_PHY_INIT_CFG_LANE(o, v, l)        \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .lane_mask = l,         \
++      }
++
++/* set of registers with offsets different per-PHY */
++enum qphy_reg_layout {
++      /* Common block control registers */
++      QPHY_COM_SW_RESET,
++      QPHY_COM_POWER_DOWN_CONTROL,
++      QPHY_COM_START_CONTROL,
++      QPHY_COM_PCS_READY_STATUS,
++      /* PCS registers */
++      QPHY_PLL_LOCK_CHK_DLY_TIME,
++      QPHY_FLL_CNTRL1,
++      QPHY_FLL_CNTRL2,
++      QPHY_FLL_CNT_VAL_L,
++      QPHY_FLL_CNT_VAL_H_TOL,
++      QPHY_FLL_MAN_CODE,
++      QPHY_SW_RESET,
++      QPHY_START_CTRL,
++      QPHY_PCS_READY_STATUS,
++      QPHY_PCS_STATUS,
++      QPHY_PCS_AUTONOMOUS_MODE_CTRL,
++      QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
++      QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
++      QPHY_PCS_POWER_DOWN_CONTROL,
++      /* PCS_MISC registers */
++      QPHY_PCS_MISC_TYPEC_CTRL,
++      /* Keep last to ensure regs_layout arrays are properly initialized */
++      QPHY_LAYOUT_SIZE
++};
++
++static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x168,
++};
++
++static const unsigned int ipq_pciephy_gen3_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                         = 0x00,
++      [QPHY_START_CTRL]                       = 0x44,
++      [QPHY_PCS_STATUS]                       = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]           = 0x40,
++};
++
++static const unsigned int pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_COM_SW_RESET]             = 0x400,
++      [QPHY_COM_POWER_DOWN_CONTROL]   = 0x404,
++      [QPHY_COM_START_CONTROL]        = 0x408,
++      [QPHY_COM_PCS_READY_STATUS]     = 0x448,
++      [QPHY_PLL_LOCK_CHK_DLY_TIME]    = 0xa8,
++      [QPHY_FLL_CNTRL1]               = 0xc4,
++      [QPHY_FLL_CNTRL2]               = 0xc8,
++      [QPHY_FLL_CNT_VAL_L]            = 0xcc,
++      [QPHY_FLL_CNT_VAL_H_TOL]        = 0xd0,
++      [QPHY_FLL_MAN_CODE]             = 0xd4,
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++};
++
++static const unsigned int usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_FLL_CNTRL1]               = 0xc0,
++      [QPHY_FLL_CNTRL2]               = 0xc4,
++      [QPHY_FLL_CNT_VAL_L]            = 0xc8,
++      [QPHY_FLL_CNT_VAL_H_TOL]        = 0xcc,
++      [QPHY_FLL_MAN_CODE]             = 0xd0,
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x17c,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d4,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0d8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178,
++};
++
++static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0dc,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
++};
++
++static const unsigned int sdm845_qmp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++};
++
++static const unsigned int sdm845_qhp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x2ac,
++};
++
++static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x308,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x314,
++};
++
++static const unsigned int qmp_v4_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x608,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x614,
++};
++
++static const unsigned int sm8350_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x1008,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x1014,
++};
++
++static const unsigned int qcm2290_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x04,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0xd8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0xdc,
++      [QPHY_PCS_STATUS]               = 0x174,
++      [QPHY_PCS_MISC_TYPEC_CTRL]      = 0x00,
++};
++
++static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x160,
++};
++
++static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x168,
++};
++
++static const unsigned int sm8250_pcie_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++};
++
++static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = QPHY_V4_PCS_UFS_PHY_START,
++      [QPHY_PCS_READY_STATUS]         = QPHY_V4_PCS_UFS_READY_STATUS,
++      [QPHY_SW_RESET]                 = QPHY_V4_PCS_UFS_SW_RESET,
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      /* PLL and Loop filter settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      /* SSC settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x0),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x40),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x19),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_RX_IDLE_DTCT_CNTRL, 0x4c),
++      QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++
++      QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x05),
++
++      QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x05),
++      QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG4, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG1, 0xa3),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0x0e),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x7e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x15),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x40),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x99),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x04),
++      /* PLL and Loop filter settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      /* SSC settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xbb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL2, 0x03),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_H_TOL, 0x42),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_MAN_CODE, 0x85),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG2, 0x08),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x29),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x53),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_TX0_LANE_MODE_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_TX0_RCV_DETECT_LVL_2, 0x12),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_GAIN, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0x61),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_LOW, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH2, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH3, 0xd3),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH4, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_LOW, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_DFE_EN_TIMER, 0x04),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL1, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(PCS_COM_G12S1_TXDEEMPH_M3P5DB, 0x10),
++      QMP_PHY_INIT_CFG(PCS_COM_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_RX_DCC_CAL_CONFIG, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_EQ_CONFIG5, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
++      QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
++      QMP_PHY_INIT_CFG(PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++      QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG1, 0x11),
++      QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_POST, 0x58),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0xf),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0xf),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x3),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0xD),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xD04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0xb),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x6),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_TX_EMP_POST1_LVL, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_TX_SLEW_CNTL, 0x0a),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x4),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x4),
++      QMP_PHY_INIT_CFG(QPHY_OSC_DTCT_ACTIONS, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x40),
++      QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x73),
++      QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_LVL, 0x99),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0xe),
++      QMP_PHY_INIT_CFG_L(QPHY_SW_RESET, 0x0),
++      QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x007),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x7e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x15),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_01, 0x59),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x40),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE, 0x04),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xbb),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG4, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_CONFIG2, 0x52),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG2, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG4, 0x1a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG5, 0x06),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SYSCLK_EN_SEL, 0x27),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE2, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BIAS_EN_CKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CLK_ENABLE1, 0xb0),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP1_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP2_MODE0, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_RESTRIM_CTRL2, 0x05),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VCO_TUNE_MAP, 0x10),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CLK_SELECT, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_HSCLK_SEL1, 0x30),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORECLK_DIV, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORE_CLK_EN, 0x73),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CMN_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SVS_MODE_CLK_SEL, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VREGCLK_DIV1, 0x22),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VREGCLK_DIV2, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BGV_TRIM, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BG_CTRL, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL0, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_TAP_EN, 0x0d),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_TX_BAND_MODE, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_LANE_MODE, 0x1a),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PARALLEL_RATE, 0x2f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE0, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE1, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE2, 0x1b),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PREAMP_CTRL_MODE1, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PREAMP_CTRL_MODE2, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE0, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE1, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE2, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_THRESH_DFE, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CGA_THRESH_DFE, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXENGINE_EN0, 0x12),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_TRAIN_TIME, 0x25),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_DFE_OVRLP_TIME, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_REFRESH_TIME, 0x05),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_ENABLE_TIME, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_VGA_GAIN, 0x26),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_GAIN, 0x12),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EQ_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_OFFSET_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PRE_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EQ_INTVAL, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EDAC_INITVAL, 0x28),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_INITB0, 0x7f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_INITB1, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RCVRDONE_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_CTRL, 0x70),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE0, 0x8b),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE2, 0x0a),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE2, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_BAND, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE0, 0x5c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE1, 0x3e),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE2, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_ENABLES, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_CNTRL, 0xa0),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_DEGLITCH_CNTRL, 0x08),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DCC_GAIN, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_EN_SIGNAL, 0xc3),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PSM_RX_EN_CAL, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_MISC_CNTRL0, 0xbc),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_TS0_TIMER, 0x7f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DLL_HIGHDATARATE, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RESETCODE_OFFSET, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_VGA_INITVAL, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RSM_START, 0x01),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_rx_tbl[] = {
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_PCS_TX_RX_CONFIG, 0x50),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_MAIN_V0_M3P5DB, 0x19),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_POST_V0_M3P5DB, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_MAIN_V0_M6DB, 0x17),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_POST_V0_M6DB, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG5, 0x9f),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_rbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x6f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr2[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr3[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRANSCEIVER_BIAS_EN, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_VMODE_CTRL1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_INTERFACE_SELECT, 0x3d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_CLKBUF_ENABLE, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RESET_TSYNC_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRAN_DRVR_EMP_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_BAND, 0x4),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_POL_INV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_DRV_LVL, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_EMP_POST1_LVL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb5),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4c),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x64),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_RX_PWM_GEAR_BAND, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_DRV_LVL, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
++      QMP_PHY_INIT_CFG(QPHY_RX_SYM_RESYNC_CTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
++      QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_CTRL2, 0x6e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SYM_RESYNC_CTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_CTRL1, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_MIN_HIBERN8_TIME, 0x9a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_INITVAL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x43),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x8a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
++
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x94),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_pcs_tbl[] = {
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x95),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xef),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x60),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x60),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x40, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x54, 2),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0xff, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f, 2),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff, 2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x97),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORE_CLK_EN, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_rbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x6f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr2[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr3[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_VMODE_CTRL1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_INTERFACE_SELECT, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_CLKBUF_ENABLE, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RESET_TSYNC_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_BAND, 0x4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_POL_INV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_DRV_LVL, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_EMP_POST1_LVL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x5),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x6e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x6e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x39),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x39),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x01),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x35),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x30),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x12),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE, 0x33),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x05),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG2, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x08),
++};
++
++static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x26),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x048),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x46),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_CFG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x50),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MISC1, 0x88),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTERNAL_DIG_CORECLK_DIV, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MODE, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_DC_LEVEL_CTRL, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x56),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x22),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_3, 0x13),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_VMODE_CTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_PI_QEC_CTRL, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_FO_GAIN_RATE2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_UCDR_PI_CONTROLS, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_AUX_DATA_TCOARSE_TFINE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_3, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_VGA_CAL_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B1, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B2, 0x5a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B4, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B0, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B1, 0xf9),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B3, 0xce),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B4, 0x62),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B0, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B1, 0x7d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B3, 0xcf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B4, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_PHPRE_CTRL, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_MARG_COARSE_CTRL2, 0x12),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG2, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG4, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG5, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_EQ_CONFIG1, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G3_RXEQEVAL_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_RXEQEVAL_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG2, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_SW_CTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_MX_CTRL2, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdx65_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0b),
++};
++
++static const struct qmp_phy_init_tbl sdx65_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_ENABLES, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_PLL_CNTL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_RX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x35),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_5, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xbb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbb),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3d, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3c, 2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xd2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x13),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_ENABLES, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_INITVAL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x01),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x04),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xd8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_TX_ADAPT_POST_THRESH, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RATE_SLEW_CNTRL1, 0x0b),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG2, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x97),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x46),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_CFG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0xd0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MISC1, 0x88),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORE_CLK_EN, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MODE, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_DC_LEVEL_CTRL, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_PI_CONTROLS, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B1, 0xcc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B3, 0xcc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B5, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B6, 0x29),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B0, 0xc5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B1, 0xad),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B2, 0xb6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B3, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B4, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B5, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B6, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B0, 0xc7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B1, 0xef),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B3, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B4, 0x81),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B5, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B6, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_PHPRE_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_0_1, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_2_3, 0x37),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_3, 0x05),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE3, 0x1f),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE210, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE210, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE210, 0x1f),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE3, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_VGA_CAL_MAN_VAL, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_IDAC_SAOFFSET, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_DAC_ENABLE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_GM_CAL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH2, 0x1f),
++};
++
++/* Register names should be validated, they might be different for this PHY */
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG2, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG3, 0x22),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_G3S2_PRE_GAIN, 0x2e),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x99),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_EQ_CONFIG1, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_RX_MARGINING_CONFIG3, 0x28),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_PRE_GAIN, 0x2e),
++};
++
++struct qmp_phy;
++
++/* struct qmp_phy_cfg - per-PHY initialization config */
++struct qmp_phy_cfg {
++      /* phy-type - PCIE/UFS/USB */
++      unsigned int type;
++      /* number of lanes provided by phy */
++      int nlanes;
++
++      /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
++      const struct qmp_phy_init_tbl *serdes_tbl;
++      int serdes_tbl_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_sec;
++      int serdes_tbl_num_sec;
++      const struct qmp_phy_init_tbl *tx_tbl;
++      int tx_tbl_num;
++      const struct qmp_phy_init_tbl *tx_tbl_sec;
++      int tx_tbl_num_sec;
++      const struct qmp_phy_init_tbl *rx_tbl;
++      int rx_tbl_num;
++      const struct qmp_phy_init_tbl *rx_tbl_sec;
++      int rx_tbl_num_sec;
++      const struct qmp_phy_init_tbl *pcs_tbl;
++      int pcs_tbl_num;
++      const struct qmp_phy_init_tbl *pcs_tbl_sec;
++      int pcs_tbl_num_sec;
++      const struct qmp_phy_init_tbl *pcs_misc_tbl;
++      int pcs_misc_tbl_num;
++      const struct qmp_phy_init_tbl *pcs_misc_tbl_sec;
++      int pcs_misc_tbl_num_sec;
++
++      /* Init sequence for DP PHY block link rates */
++      const struct qmp_phy_init_tbl *serdes_tbl_rbr;
++      int serdes_tbl_rbr_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr;
++      int serdes_tbl_hbr_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr2;
++      int serdes_tbl_hbr2_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr3;
++      int serdes_tbl_hbr3_num;
++
++      /* DP PHY callbacks */
++      int (*configure_dp_phy)(struct qmp_phy *qphy);
++      void (*configure_dp_tx)(struct qmp_phy *qphy);
++      int (*calibrate_dp_phy)(struct qmp_phy *qphy);
++      void (*dp_aux_init)(struct qmp_phy *qphy);
++
++      /* clock ids to be requested */
++      const char * const *clk_list;
++      int num_clks;
++      /* resets to be requested */
++      const char * const *reset_list;
++      int num_resets;
++      /* regulators to be requested */
++      const char * const *vreg_list;
++      int num_vregs;
++
++      /* array of registers with different offsets */
++      const unsigned int *regs;
++
++      unsigned int start_ctrl;
++      unsigned int pwrdn_ctrl;
++      unsigned int mask_com_pcs_ready;
++      /* bit offset of PHYSTATUS in QPHY_PCS_STATUS register */
++      unsigned int phy_status;
++
++      /* true, if PHY has a separate PHY_COM control block */
++      bool has_phy_com_ctrl;
++      /* true, if PHY has a reset for individual lanes */
++      bool has_lane_rst;
++      /* true, if PHY needs delay after POWER_DOWN */
++      bool has_pwrdn_delay;
++      /* power_down delay in usec */
++      int pwrdn_delay_min;
++      int pwrdn_delay_max;
++
++      /* true, if PHY has a separate DP_COM control block */
++      bool has_phy_dp_com_ctrl;
++      /* true, if PHY has secondary tx/rx lanes to be configured */
++      bool is_dual_lane_phy;
++
++      /* true, if PCS block has no separate SW_RESET register */
++      bool no_pcs_sw_reset;
++};
++
++struct qmp_phy_combo_cfg {
++      const struct qmp_phy_cfg *usb_cfg;
++      const struct qmp_phy_cfg *dp_cfg;
++};
++
++/**
++ * struct qmp_phy - per-lane phy descriptor
++ *
++ * @phy: generic phy
++ * @cfg: phy specific configuration
++ * @serdes: iomapped memory space for phy's serdes (i.e. PLL)
++ * @tx: iomapped memory space for lane's tx
++ * @rx: iomapped memory space for lane's rx
++ * @pcs: iomapped memory space for lane's pcs
++ * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
++ * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
++ * @pcs_misc: iomapped memory space for lane's pcs_misc
++ * @pipe_clk: pipe clock
++ * @index: lane index
++ * @qmp: QMP phy to which this lane belongs
++ * @lane_rst: lane's reset controller
++ * @mode: current PHY mode
++ * @dp_aux_cfg: Display port aux config
++ * @dp_opts: Display port optional config
++ * @dp_clks: Display port clocks
++ */
++struct qmp_phy {
++      struct phy *phy;
++      const struct qmp_phy_cfg *cfg;
++      void __iomem *serdes;
++      void __iomem *tx;
++      void __iomem *rx;
++      void __iomem *pcs;
++      void __iomem *tx2;
++      void __iomem *rx2;
++      void __iomem *pcs_misc;
++      struct clk *pipe_clk;
++      unsigned int index;
++      struct qcom_qmp *qmp;
++      struct reset_control *lane_rst;
++      enum phy_mode mode;
++      unsigned int dp_aux_cfg;
++      struct phy_configure_opts_dp dp_opts;
++      struct qmp_phy_dp_clks *dp_clks;
++};
++
++struct qmp_phy_dp_clks {
++      struct qmp_phy *qphy;
++      struct clk_hw dp_link_hw;
++      struct clk_hw dp_pixel_hw;
++};
++
++/**
++ * struct qcom_qmp - structure holding QMP phy block attributes
++ *
++ * @dev: device
++ * @dp_com: iomapped memory space for phy's dp_com control block
++ *
++ * @clks: array of clocks required by phy
++ * @resets: array of resets required by phy
++ * @vregs: regulator supplies bulk data
++ *
++ * @phys: array of per-lane phy descriptors
++ * @phy_mutex: mutex lock for PHY common block initialization
++ * @init_count: phy common block initialization count
++ * @ufs_reset: optional UFS PHY reset handle
++ */
++struct qcom_qmp {
++      struct device *dev;
++      void __iomem *dp_com;
++
++      struct clk_bulk_data *clks;
++      struct reset_control **resets;
++      struct regulator_bulk_data *vregs;
++
++      struct qmp_phy **phys;
++
++      struct mutex phy_mutex;
++      int init_count;
++
++      struct reset_control *ufs_reset;
++};
++
++static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy);
++static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy);
++static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy);
++static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy);
++
++static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy);
++static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy);
++static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy);
++static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy);
++
++static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
++{
++      u32 reg;
++
++      reg = readl(base + offset);
++      reg |= val;
++      writel(reg, base + offset);
++
++      /* ensure that above write is through */
++      readl(base + offset);
++}
++
++static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
++{
++      u32 reg;
++
++      reg = readl(base + offset);
++      reg &= ~val;
++      writel(reg, base + offset);
++
++      /* ensure that above write is through */
++      readl(base + offset);
++}
++
++/* list of clocks required by phy */
++static const char * const msm8996_phy_clk_l[] = {
++      "aux", "cfg_ahb", "ref",
++};
++
++static const char * const msm8996_ufs_phy_clk_l[] = {
++      "ref",
++};
++
++static const char * const qmp_v3_phy_clk_l[] = {
++      "aux", "cfg_ahb", "ref", "com_aux",
++};
++
++static const char * const sdm845_pciephy_clk_l[] = {
++      "aux", "cfg_ahb", "ref", "refgen",
++};
++
++static const char * const qmp_v4_phy_clk_l[] = {
++      "aux", "ref_clk_src", "ref", "com_aux",
++};
++
++/* the primary usb3 phy on sm8250 doesn't have a ref clock */
++static const char * const qmp_v4_sm8250_usbphy_clk_l[] = {
++      "aux", "ref_clk_src", "com_aux"
++};
++
++static const char * const sm8450_ufs_phy_clk_l[] = {
++      "qref", "ref", "ref_aux",
++};
++
++static const char * const sdm845_ufs_phy_clk_l[] = {
++      "ref", "ref_aux",
++};
++
++/* usb3 phy on sdx55 doesn't have com_aux clock */
++static const char * const qmp_v4_sdx55_usbphy_clk_l[] = {
++      "aux", "cfg_ahb", "ref"
++};
++
++static const char * const qcm2290_usb3phy_clk_l[] = {
++      "cfg_ahb", "ref", "com_aux",
++};
++
++/* list of resets */
++static const char * const msm8996_pciephy_reset_l[] = {
++      "phy", "common", "cfg",
++};
++
++static const char * const msm8996_usb3phy_reset_l[] = {
++      "phy", "common",
++};
++
++static const char * const sc7180_usb3phy_reset_l[] = {
++      "phy",
++};
++
++static const char * const qcm2290_usb3phy_reset_l[] = {
++      "phy_phy", "phy",
++};
++
++static const char * const sdm845_pciephy_reset_l[] = {
++      "phy",
++};
++
++/* list of regulators */
++static const char * const qmp_phy_vreg_l[] = {
++      "vdda-phy", "vdda-pll",
++};
++
++static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq8074_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq8074_usb3_serdes_tbl),
++      .tx_tbl                 = msm8996_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_usb3_tx_tbl),
++      .rx_tbl                 = ipq8074_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq8074_usb3_rx_tbl),
++      .pcs_tbl                = ipq8074_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq8074_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++};
++
++static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 3,
++
++      .serdes_tbl             = msm8996_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_pcie_serdes_tbl),
++      .tx_tbl                 = msm8996_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_pcie_tx_tbl),
++      .rx_tbl                 = msm8996_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_pcie_rx_tbl),
++      .pcs_tbl                = msm8996_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8996_pcie_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | PLL_READY_GATE_EN,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .mask_com_pcs_ready     = PCS_READY,
++      .phy_status             = PHYSTATUS,
++
++      .has_phy_com_ctrl       = true,
++      .has_lane_rst           = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg msm8996_ufs_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8996_ufs_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_ufs_serdes_tbl),
++      .tx_tbl                 = msm8996_ufs_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_ufs_tx_tbl),
++      .rx_tbl                 = msm8996_ufs_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_ufs_rx_tbl),
++
++      .clk_list               = msm8996_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_ufs_phy_clk_l),
++
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++
++      .regs                   = msm8996_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8996_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_usb3_serdes_tbl),
++      .tx_tbl                 = msm8996_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_usb3_tx_tbl),
++      .rx_tbl                 = msm8996_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_usb3_rx_tbl),
++      .pcs_tbl                = msm8996_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8996_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++};
++
++static const char * const ipq8074_pciephy_clk_l[] = {
++      "aux", "cfg_ahb",
++};
++/* list of resets */
++static const char * const ipq8074_pciephy_reset_l[] = {
++      "phy", "common",
++};
++
++static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq8074_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq8074_pcie_serdes_tbl),
++      .tx_tbl                 = ipq8074_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_tx_tbl),
++      .rx_tbl                 = ipq8074_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_rx_tbl),
++      .pcs_tbl                = ipq8074_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq8074_pcie_pcs_tbl),
++      .clk_list               = ipq8074_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(ipq8074_pciephy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = NULL,
++      .num_vregs              = 0,
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_phy_com_ctrl       = false,
++      .has_lane_rst           = false,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq6018_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq6018_pcie_serdes_tbl),
++      .tx_tbl                 = ipq6018_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(ipq6018_pcie_tx_tbl),
++      .rx_tbl                 = ipq6018_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq6018_pcie_rx_tbl),
++      .pcs_tbl                = ipq6018_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq6018_pcie_pcs_tbl),
++      .clk_list               = ipq8074_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(ipq8074_pciephy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = NULL,
++      .num_vregs              = 0,
++      .regs                   = ipq_pciephy_gen3_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++
++      .has_phy_com_ctrl       = false,
++      .has_lane_rst           = false,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sdm845_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sdm845_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sdm845_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sdm845_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sdm845_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sdm845_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_qmp_pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdm845_qhp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sdm845_qhp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_qhp_pcie_serdes_tbl),
++      .tx_tbl                 = sdm845_qhp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_qhp_pcie_tx_tbl),
++      .rx_tbl                 = sdm845_qhp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_qhp_pcie_rx_tbl),
++      .pcs_tbl                = sdm845_qhp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_qhp_pcie_pcs_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_qhp_pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sm8250_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
++      .serdes_tbl_sec         = sm8250_qmp_gen3x1_pcie_serdes_tbl,
++      .serdes_tbl_num_sec     = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_serdes_tbl),
++      .tx_tbl                 = sm8250_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sm8250_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
++      .rx_tbl_sec             = sm8250_qmp_gen3x1_pcie_rx_tbl,
++      .rx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_rx_tbl),
++      .pcs_tbl                = sm8250_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
++      .pcs_tbl_sec            = sm8250_qmp_gen3x1_pcie_pcs_tbl,
++      .pcs_tbl_num_sec                = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8250_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
++      .pcs_misc_tbl_sec               = sm8250_qmp_gen3x1_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num_sec   = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sm8250_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sm8250_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
++      .tx_tbl_sec             = sm8250_qmp_gen3x2_pcie_tx_tbl,
++      .tx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_tx_tbl),
++      .rx_tbl                 = sm8250_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
++      .rx_tbl_sec             = sm8250_qmp_gen3x2_pcie_rx_tbl,
++      .rx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_rx_tbl),
++      .pcs_tbl                = sm8250_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
++      .pcs_tbl_sec            = sm8250_qmp_gen3x2_pcie_pcs_tbl,
++      .pcs_tbl_num_sec                = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8250_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
++      .pcs_misc_tbl_sec               = sm8250_qmp_gen3x2_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num_sec   = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc7180_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v3_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v3_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v3_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v3_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v3_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v3_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v3_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v3_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v3_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sc7180_usb3dpphy_cfg = {
++      .usb_cfg                = &sc7180_usb3phy_cfg,
++      .dp_cfg                 = &sc7180_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sdm845_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
++      .tx_tbl                 = sdm845_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
++      .rx_tbl                 = sdm845_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
++      .pcs_tbl                = sdm845_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm6115_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm6115_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
++      .rx_tbl                 = sm6115_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
++      .pcs_tbl                = sm6115_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm6115_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++
++      .is_dual_lane_phy       = false,
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8998_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8998_pcie_serdes_tbl),
++      .tx_tbl                 = msm8998_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8998_pcie_tx_tbl),
++      .rx_tbl                 = msm8998_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8998_pcie_rx_tbl),
++      .pcs_tbl                = msm8998_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8998_pcie_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++};
++
++static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8998_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl),
++      .tx_tbl                 = msm8998_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8998_usb3_tx_tbl),
++      .rx_tbl                 = msm8998_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
++      .pcs_tbl                = msm8998_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8150_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8150_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8150_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8150_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8150_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_usb3_tx_tbl),
++      .rx_tbl                 = sm8150_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_usb3_rx_tbl),
++      .pcs_tbl                = sm8150_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sc8180x_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sc8180x_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sc8180x_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sc8180x_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sc8180x_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sc8180x_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sc8180x_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v4_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v4_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v4_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v4_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v4_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v4_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sc8180x_usb3dpphy_cfg = {
++      .usb_cfg                = &sm8150_usb3phy_cfg,
++      .dp_cfg                 = &sc8180x_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8150_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8150_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8150_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8250_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_usb3_tx_tbl),
++      .rx_tbl                 = sm8250_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_usb3_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_sm8250_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8250_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8250_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8250_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v4_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v4_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v4_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v4_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v4_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v4_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sm8250_usb3dpphy_cfg = {
++      .usb_cfg                = &sm8250_usb3phy_cfg,
++      .dp_cfg                 = &sm8250_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sdx55_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx55_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sdx55_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx55_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_sdx55_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sdx55_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdx55_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sdx55_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx55_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sdx55_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx55_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sdx55_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdx55_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sdx55_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sdx55_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS_4_20,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sdx65_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx65_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sdx65_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx65_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_sdx55_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8350_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8350_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8350_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8350_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8350_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8350_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_usb3_tx_tbl),
++      .rx_tbl                 = sm8350_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_usb3_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_sm8250_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8350_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8350_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8350_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8350_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8350_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8350_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8350_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
++      .clk_list               = sm8450_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sm8450_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8450_qmp_gen3x1_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sm8450_qmp_gen3x1_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_serdes_tbl),
++      .tx_tbl                 = sm8450_qmp_gen3x1_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_tx_tbl),
++      .rx_tbl                 = sm8450_qmp_gen3x1_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_rx_tbl),
++      .pcs_tbl                = sm8450_qmp_gen3x1_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8450_qmp_gen3x1_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8450_qmp_gen4x2_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sm8450_qmp_gen4x2_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_serdes_tbl),
++      .tx_tbl                 = sm8450_qmp_gen4x2_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_tx_tbl),
++      .rx_tbl                 = sm8450_qmp_gen4x2_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_rx_tbl),
++      .pcs_tbl                = sm8450_qmp_gen4x2_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8450_qmp_gen4x2_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS_4_20,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qcm2290_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
++      .tx_tbl                 = qcm2290_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_tx_tbl),
++      .rx_tbl                 = qcm2290_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_rx_tbl),
++      .pcs_tbl                = qcm2290_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
++      .clk_list               = qcm2290_usb3phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qcm2290_usb3phy_clk_l),
++      .reset_list             = qcm2290_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(qcm2290_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qcm2290_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static void qcom_qmp_phy_configure_lane(void __iomem *base,
++                                      const unsigned int *regs,
++                                      const struct qmp_phy_init_tbl tbl[],
++                                      int num,
++                                      u8 lane_mask)
++{
++      int i;
++      const struct qmp_phy_init_tbl *t = tbl;
++
++      if (!t)
++              return;
++
++      for (i = 0; i < num; i++, t++) {
++              if (!(t->lane_mask & lane_mask))
++                      continue;
++
++              if (t->in_layout)
++                      writel(t->val, base + regs[t->offset]);
++              else
++                      writel(t->val, base + t->offset);
++      }
++}
++
++static void qcom_qmp_phy_configure(void __iomem *base,
++                                 const unsigned int *regs,
++                                 const struct qmp_phy_init_tbl tbl[],
++                                 int num)
++{
++      qcom_qmp_phy_configure_lane(base, regs, tbl, num, 0xff);
++}
++
++static int qcom_qmp_phy_serdes_init(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
++      int serdes_tbl_num = cfg->serdes_tbl_num;
++      int ret;
++
++      qcom_qmp_phy_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num);
++      if (cfg->serdes_tbl_sec)
++              qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl_sec,
++                                     cfg->serdes_tbl_num_sec);
++
++      if (cfg->type == PHY_TYPE_DP) {
++              switch (dp_opts->link_rate) {
++              case 1620:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_rbr,
++                                             cfg->serdes_tbl_rbr_num);
++                      break;
++              case 2700:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr,
++                                             cfg->serdes_tbl_hbr_num);
++                      break;
++              case 5400:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr2,
++                                             cfg->serdes_tbl_hbr2_num);
++                      break;
++              case 8100:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr3,
++                                             cfg->serdes_tbl_hbr3_num);
++                      break;
++              default:
++                      /* Other link rates aren't supported */
++                      return -EINVAL;
++              }
++      }
++
++
++      if (cfg->has_phy_com_ctrl) {
++              void __iomem *status;
++              unsigned int mask, val;
++
++              qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET], SW_RESET);
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
++                           SERDES_START | PCS_START);
++
++              status = serdes + cfg->regs[QPHY_COM_PCS_READY_STATUS];
++              mask = cfg->mask_com_pcs_ready;
++
++              ret = readl_poll_timeout(status, val, (val & mask), 10,
++                                       PHY_INIT_COMPLETE_TIMEOUT);
++              if (ret) {
++                      dev_err(qmp->dev,
++                              "phy common block init timed-out\n");
++                      return ret;
++              }
++      }
++
++      return 0;
++}
++
++static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy)
++{
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      /* Turn on BIAS current for PHY/PLL */
++      writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX |
++             QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL,
++             qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_LANE_0_1_PWRDN |
++             DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN |
++             DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(QSERDES_V3_COM_BIAS_EN |
++             QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN |
++             QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL |
++             QSERDES_V3_COM_CLKBUF_RX_DRIVE_L,
++             qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0x24, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
++      writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
++      writel(0xbb, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
++      qphy->dp_aux_cfg = 0;
++
++      writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
++             PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
++             PHY_AUX_REQ_ERR_MASK,
++             qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
++}
++
++static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = {
++      { 0x00, 0x0c, 0x15, 0x1a },
++      { 0x02, 0x0e, 0x16, 0xff },
++      { 0x02, 0x11, 0xff, 0xff },
++      { 0x04, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_voltage_swing_hbr3_hbr2[4][4] = {
++      { 0x02, 0x12, 0x16, 0x1a },
++      { 0x09, 0x19, 0x1f, 0xff },
++      { 0x10, 0x1f, 0xff, 0xff },
++      { 0x1f, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = {
++      { 0x00, 0x0c, 0x14, 0x19 },
++      { 0x00, 0x0b, 0x12, 0xff },
++      { 0x00, 0x0b, 0xff, 0xff },
++      { 0x04, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
++      { 0x08, 0x0f, 0x16, 0x1f },
++      { 0x11, 0x1e, 0x1f, 0xff },
++      { 0x19, 0x1f, 0xff, 0xff },
++      { 0x1f, 0xff, 0xff, 0xff }
++};
++
++static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy,
++              unsigned int drv_lvl_reg, unsigned int emp_post_reg)
++{
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      unsigned int v_level = 0, p_level = 0;
++      u8 voltage_swing_cfg, pre_emphasis_cfg;
++      int i;
++
++      for (i = 0; i < dp_opts->lanes; i++) {
++              v_level = max(v_level, dp_opts->voltage[i]);
++              p_level = max(p_level, dp_opts->pre[i]);
++      }
++
++      if (dp_opts->link_rate <= 2700) {
++              voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
++              pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
++      } else {
++              voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr3_hbr2[v_level][p_level];
++              pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr3_hbr2[v_level][p_level];
++      }
++
++      /* TODO: Move check to config check */
++      if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
++              return -EINVAL;
++
++      /* Enable MUX to use Cursor values from these registers */
++      voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
++      pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
++
++      writel(voltage_swing_cfg, qphy->tx + drv_lvl_reg);
++      writel(pre_emphasis_cfg, qphy->tx + emp_post_reg);
++      writel(voltage_swing_cfg, qphy->tx2 + drv_lvl_reg);
++      writel(pre_emphasis_cfg, qphy->tx2 + emp_post_reg);
++
++      return 0;
++}
++
++static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)
++{
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 bias_en, drvr_en;
++
++      if (qcom_qmp_phy_configure_dp_swing(qphy,
++                              QSERDES_V3_TX_TX_DRV_LVL,
++                              QSERDES_V3_TX_TX_EMP_POST1_LVL) < 0)
++              return;
++
++      if (dp_opts->lanes == 1) {
++              bias_en = 0x3e;
++              drvr_en = 0x13;
++      } else {
++              bias_en = 0x3f;
++              drvr_en = 0x10;
++      }
++
++      writel(drvr_en, qphy->tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
++      writel(bias_en, qphy->tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
++      writel(drvr_en, qphy->tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
++      writel(bias_en, qphy->tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
++}
++
++static bool qcom_qmp_phy_configure_dp_mode(struct qmp_phy *qphy)
++{
++      u32 val;
++      bool reverse = false;
++
++      val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++            DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN;
++
++      /*
++       * TODO: Assume orientation is CC1 for now and two lanes, need to
++       * use type-c connector to understand orientation and lanes.
++       *
++       * Otherwise val changes to be like below if this code understood
++       * the orientation of the type-c cable.
++       *
++       * if (lane_cnt == 4 || orientation == ORIENTATION_CC2)
++       *      val |= DP_PHY_PD_CTL_LANE_0_1_PWRDN;
++       * if (lane_cnt == 4 || orientation == ORIENTATION_CC1)
++       *      val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
++       * if (orientation == ORIENTATION_CC2)
++       *      writel(0x4c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
++       */
++      val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
++      writel(val, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(0x5c, qphy->pcs + QSERDES_DP_PHY_MODE);
++
++      return reverse;
++}
++
++static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 phy_vco_div, status;
++      unsigned long pixel_freq;
++
++      qcom_qmp_phy_configure_dp_mode(qphy);
++
++      writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
++      writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              phy_vco_div = 0x1;
++              pixel_freq = 1620000000UL / 2;
++              break;
++      case 2700:
++              phy_vco_div = 0x1;
++              pixel_freq = 2700000000UL / 2;
++              break;
++      case 5400:
++              phy_vco_div = 0x2;
++              pixel_freq = 5400000000UL / 4;
++              break;
++      case 8100:
++              phy_vco_div = 0x0;
++              pixel_freq = 8100000000UL / 6;
++              break;
++      default:
++              /* Other link rates aren't supported */
++              return -EINVAL;
++      }
++      writel(phy_vco_div, qphy->pcs + QSERDES_V3_DP_PHY_VCO_DIV);
++
++      clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
++      clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
++
++      writel(0x04, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      writel(0x20, qphy->serdes + QSERDES_V3_COM_RESETSM_CNTRL);
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V3_COM_C_READY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
++      udelay(2000);
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      return readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000);
++}
++
++/*
++ * We need to calibrate the aux setting here as many times
++ * as the caller tries
++ */
++static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy)
++{
++      static const u8 cfg1_settings[] = { 0x13, 0x23, 0x1d };
++      u8 val;
++
++      qphy->dp_aux_cfg++;
++      qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
++      val = cfg1_settings[qphy->dp_aux_cfg];
++
++      writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++
++      return 0;
++}
++
++static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy)
++{
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      /* Turn on BIAS current for PHY/PLL */
++      writel(0x17, qphy->serdes + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
++      writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
++      writel(0xb7, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
++      qphy->dp_aux_cfg = 0;
++
++      writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
++             PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
++             PHY_AUX_REQ_ERR_MASK,
++             qphy->pcs + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
++}
++
++static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy)
++{
++      /* Program default values before writing proper values */
++      writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
++      writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
++
++      writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++      writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++
++      qcom_qmp_phy_configure_dp_swing(qphy,
++                      QSERDES_V4_TX_TX_DRV_LVL,
++                      QSERDES_V4_TX_TX_EMP_POST1_LVL);
++}
++
++static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 phy_vco_div, status;
++      unsigned long pixel_freq;
++      u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
++      bool reverse;
++
++      writel(0x0f, qphy->pcs + QSERDES_V4_DP_PHY_CFG_1);
++
++      reverse = qcom_qmp_phy_configure_dp_mode(qphy);
++
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++
++      writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL);
++      writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL);
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              phy_vco_div = 0x1;
++              pixel_freq = 1620000000UL / 2;
++              break;
++      case 2700:
++              phy_vco_div = 0x1;
++              pixel_freq = 2700000000UL / 2;
++              break;
++      case 5400:
++              phy_vco_div = 0x2;
++              pixel_freq = 5400000000UL / 4;
++              break;
++      case 8100:
++              phy_vco_div = 0x0;
++              pixel_freq = 8100000000UL / 6;
++              break;
++      default:
++              /* Other link rates aren't supported */
++              return -EINVAL;
++      }
++      writel(phy_vco_div, qphy->pcs + QSERDES_V4_DP_PHY_VCO_DIV);
++
++      clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
++      clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
++
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      writel(0x20, qphy->serdes + QSERDES_V4_COM_RESETSM_CNTRL);
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_C_READY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      /*
++       * At least for 7nm DP PHY this has to be done after enabling link
++       * clock.
++       */
++
++      if (dp_opts->lanes == 1) {
++              bias0_en = reverse ? 0x3e : 0x15;
++              bias1_en = reverse ? 0x15 : 0x3e;
++              drvr0_en = reverse ? 0x13 : 0x10;
++              drvr1_en = reverse ? 0x10 : 0x13;
++      } else if (dp_opts->lanes == 2) {
++              bias0_en = reverse ? 0x3f : 0x15;
++              bias1_en = reverse ? 0x15 : 0x3f;
++              drvr0_en = 0x10;
++              drvr1_en = 0x10;
++      } else {
++              bias0_en = 0x3f;
++              bias1_en = 0x3f;
++              drvr0_en = 0x10;
++              drvr1_en = 0x10;
++      }
++
++      writel(drvr0_en, qphy->tx + QSERDES_V4_TX_HIGHZ_DRVR_EN);
++      writel(bias0_en, qphy->tx + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
++      writel(drvr1_en, qphy->tx2 + QSERDES_V4_TX_HIGHZ_DRVR_EN);
++      writel(bias1_en, qphy->tx2 + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
++
++      writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
++      udelay(2000);
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x0a, qphy->tx + QSERDES_V4_TX_TX_POL_INV);
++      writel(0x0a, qphy->tx2 + QSERDES_V4_TX_TX_POL_INV);
++
++      writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
++      writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
++
++      writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++      writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++
++      return 0;
++}
++
++/*
++ * We need to calibrate the aux setting here as many times
++ * as the caller tries
++ */
++static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy)
++{
++      static const u8 cfg1_settings[] = { 0x20, 0x13, 0x23, 0x1d };
++      u8 val;
++
++      qphy->dp_aux_cfg++;
++      qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
++      val = cfg1_settings[qphy->dp_aux_cfg];
++
++      writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++
++      return 0;
++}
++
++static int qcom_qmp_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
++{
++      const struct phy_configure_opts_dp *dp_opts = &opts->dp;
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      memcpy(&qphy->dp_opts, dp_opts, sizeof(*dp_opts));
++      if (qphy->dp_opts.set_voltages) {
++              cfg->configure_dp_tx(qphy);
++              qphy->dp_opts.set_voltages = 0;
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_dp_phy_calibrate(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      if (cfg->calibrate_dp_phy)
++              return cfg->calibrate_dp_phy(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_com_init(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *dp_com = qmp->dp_com;
++      int ret, i;
++
++      mutex_lock(&qmp->phy_mutex);
++      if (qmp->init_count++) {
++              mutex_unlock(&qmp->phy_mutex);
++              return 0;
++      }
++
++      /* turn on regulator supplies */
++      ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
++      if (ret) {
++              dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
++              goto err_unlock;
++      }
++
++      for (i = 0; i < cfg->num_resets; i++) {
++              ret = reset_control_assert(qmp->resets[i]);
++              if (ret) {
++                      dev_err(qmp->dev, "%s reset assert failed\n",
++                              cfg->reset_list[i]);
++                      goto err_disable_regulators;
++              }
++      }
++
++      for (i = cfg->num_resets - 1; i >= 0; i--) {
++              ret = reset_control_deassert(qmp->resets[i]);
++              if (ret) {
++                      dev_err(qmp->dev, "%s reset deassert failed\n",
++                              qphy->cfg->reset_list[i]);
++                      goto err_assert_reset;
++              }
++      }
++
++      ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
++      if (ret)
++              goto err_assert_reset;
++
++      if (cfg->has_phy_dp_com_ctrl) {
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_POWER_DOWN_CTRL,
++                           SW_PWRDN);
++              /* override hardware control for reset of qmp phy */
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
++                           SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
++                           SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
++
++              /* Default type-c orientation, i.e CC1 */
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_TYPEC_CTRL, 0x02);
++
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_PHY_MODE_CTRL,
++                           USB3_MODE | DP_MODE);
++
++              /* bring both QMP USB and QMP DP PHYs PCS block out of reset */
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
++                           SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
++                           SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
++
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_SWI_CTRL, 0x03);
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
++      }
++
++      if (cfg->has_phy_com_ctrl) {
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
++                           SW_PWRDN);
++      } else {
++              if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
++                      qphy_setbits(pcs,
++                                      cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++                                      cfg->pwrdn_ctrl);
++              else
++                      qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL,
++                                      cfg->pwrdn_ctrl);
++      }
++
++      mutex_unlock(&qmp->phy_mutex);
++
++      return 0;
++
++err_assert_reset:
++      while (++i < cfg->num_resets)
++              reset_control_assert(qmp->resets[i]);
++err_disable_regulators:
++      regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
++err_unlock:
++      mutex_unlock(&qmp->phy_mutex);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_com_exit(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      int i = cfg->num_resets;
++
++      mutex_lock(&qmp->phy_mutex);
++      if (--qmp->init_count) {
++              mutex_unlock(&qmp->phy_mutex);
++              return 0;
++      }
++
++      reset_control_assert(qmp->ufs_reset);
++      if (cfg->has_phy_com_ctrl) {
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
++                           SERDES_START | PCS_START);
++              qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET],
++                           SW_RESET);
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
++                           SW_PWRDN);
++      }
++
++      while (--i >= 0)
++              reset_control_assert(qmp->resets[i]);
++
++      clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++
++      regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
++
++      mutex_unlock(&qmp->phy_mutex);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_init(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      int ret;
++      dev_vdbg(qmp->dev, "Initializing QMP phy\n");
++
++      if (cfg->no_pcs_sw_reset) {
++              /*
++               * Get UFS reset, which is delayed until now to avoid a
++               * circular dependency where UFS needs its PHY, but the PHY
++               * needs this UFS reset.
++               */
++              if (!qmp->ufs_reset) {
++                      qmp->ufs_reset =
++                              devm_reset_control_get_exclusive(qmp->dev,
++                                                               "ufsphy");
++
++                      if (IS_ERR(qmp->ufs_reset)) {
++                              ret = PTR_ERR(qmp->ufs_reset);
++                              dev_err(qmp->dev,
++                                      "failed to get UFS reset: %d\n",
++                                      ret);
++
++                              qmp->ufs_reset = NULL;
++                              return ret;
++                      }
++              }
++
++              ret = reset_control_assert(qmp->ufs_reset);
++              if (ret)
++                      return ret;
++      }
++
++      ret = qcom_qmp_phy_com_init(qphy);
++      if (ret)
++              return ret;
++
++      if (cfg->type == PHY_TYPE_DP)
++              cfg->dp_aux_init(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_power_on(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *tx = qphy->tx;
++      void __iomem *rx = qphy->rx;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++      void __iomem *status;
++      unsigned int mask, val, ready;
++      int ret;
++
++      qcom_qmp_phy_serdes_init(qphy);
++
++      if (cfg->has_lane_rst) {
++              ret = reset_control_deassert(qphy->lane_rst);
++              if (ret) {
++                      dev_err(qmp->dev, "lane%d reset deassert failed\n",
++                              qphy->index);
++                      return ret;
++              }
++      }
++
++      ret = clk_prepare_enable(qphy->pipe_clk);
++      if (ret) {
++              dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
++              goto err_reset_lane;
++      }
++
++      /* Tx, Rx, and PCS configurations */
++      qcom_qmp_phy_configure_lane(tx, cfg->regs,
++                                  cfg->tx_tbl, cfg->tx_tbl_num, 1);
++      if (cfg->tx_tbl_sec)
++              qcom_qmp_phy_configure_lane(tx, cfg->regs, cfg->tx_tbl_sec,
++                                          cfg->tx_tbl_num_sec, 1);
++
++      /* Configuration for other LANE for USB-DP combo PHY */
++      if (cfg->is_dual_lane_phy) {
++              qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
++                                          cfg->tx_tbl, cfg->tx_tbl_num, 2);
++              if (cfg->tx_tbl_sec)
++                      qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
++                                                  cfg->tx_tbl_sec,
++                                                  cfg->tx_tbl_num_sec, 2);
++      }
++
++      /* Configure special DP tx tunings */
++      if (cfg->type == PHY_TYPE_DP)
++              cfg->configure_dp_tx(qphy);
++
++      qcom_qmp_phy_configure_lane(rx, cfg->regs,
++                                  cfg->rx_tbl, cfg->rx_tbl_num, 1);
++      if (cfg->rx_tbl_sec)
++              qcom_qmp_phy_configure_lane(rx, cfg->regs,
++                                          cfg->rx_tbl_sec, cfg->rx_tbl_num_sec, 1);
++
++      if (cfg->is_dual_lane_phy) {
++              qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
++                                          cfg->rx_tbl, cfg->rx_tbl_num, 2);
++              if (cfg->rx_tbl_sec)
++                      qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
++                                                  cfg->rx_tbl_sec,
++                                                  cfg->rx_tbl_num_sec, 2);
++      }
++
++      /* Configure link rate, swing, etc. */
++      if (cfg->type == PHY_TYPE_DP) {
++              cfg->configure_dp_phy(qphy);
++      } else {
++              qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
++              if (cfg->pcs_tbl_sec)
++                      qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl_sec,
++                                             cfg->pcs_tbl_num_sec);
++      }
++
++      ret = reset_control_deassert(qmp->ufs_reset);
++      if (ret)
++              goto err_disable_pipe_clk;
++
++      qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl,
++                             cfg->pcs_misc_tbl_num);
++      if (cfg->pcs_misc_tbl_sec)
++              qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl_sec,
++                                     cfg->pcs_misc_tbl_num_sec);
++
++      /*
++       * Pull out PHY from POWER DOWN state.
++       * This is active low enable signal to power-down PHY.
++       */
++      if(cfg->type == PHY_TYPE_PCIE)
++              qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
++
++      if (cfg->has_pwrdn_delay)
++              usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
++
++      if (cfg->type != PHY_TYPE_DP) {
++              /* Pull PHY out of reset state */
++              if (!cfg->no_pcs_sw_reset)
++                      qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
++              /* start SerDes and Phy-Coding-Sublayer */
++              qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
++
++              if (cfg->type == PHY_TYPE_UFS) {
++                      status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
++                      mask = PCS_READY;
++                      ready = PCS_READY;
++              } else {
++                      status = pcs + cfg->regs[QPHY_PCS_STATUS];
++                      mask = cfg->phy_status;
++                      ready = 0;
++              }
++
++              ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
++                                       PHY_INIT_COMPLETE_TIMEOUT);
++              if (ret) {
++                      dev_err(qmp->dev, "phy initialization timed-out\n");
++                      goto err_disable_pipe_clk;
++              }
++      }
++      return 0;
++
++err_disable_pipe_clk:
++      clk_disable_unprepare(qphy->pipe_clk);
++err_reset_lane:
++      if (cfg->has_lane_rst)
++              reset_control_assert(qphy->lane_rst);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_power_off(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      clk_disable_unprepare(qphy->pipe_clk);
++
++      if (cfg->type == PHY_TYPE_DP) {
++              /* Assert DP PHY power down */
++              writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++      } else {
++              /* PHY reset */
++              if (!cfg->no_pcs_sw_reset)
++                      qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
++
++              /* stop SerDes and Phy-Coding-Sublayer */
++              qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
++
++              /* Put PHY into POWER DOWN state: active low */
++              if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) {
++                      qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++                                   cfg->pwrdn_ctrl);
++              } else {
++                      qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL,
++                                      cfg->pwrdn_ctrl);
++              }
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_phy_exit(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      if (cfg->has_lane_rst)
++              reset_control_assert(qphy->lane_rst);
++
++      qcom_qmp_phy_com_exit(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_enable(struct phy *phy)
++{
++      int ret;
++
++      ret = qcom_qmp_phy_init(phy);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_power_on(phy);
++      if (ret)
++              qcom_qmp_phy_exit(phy);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_disable(struct phy *phy)
++{
++      int ret;
++
++      ret = qcom_qmp_phy_power_off(phy);
++      if (ret)
++              return ret;
++      return qcom_qmp_phy_exit(phy);
++}
++
++static int qcom_qmp_phy_set_mode(struct phy *phy,
++                               enum phy_mode mode, int submode)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++
++      qphy->mode = mode;
++
++      return 0;
++}
++
++static void qcom_qmp_phy_enable_autonomous_mode(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++      u32 intr_mask;
++
++      if (qphy->mode == PHY_MODE_USB_HOST_SS ||
++          qphy->mode == PHY_MODE_USB_DEVICE_SS)
++              intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
++      else
++              intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
++
++      /* Clear any pending interrupts status */
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++      /* Writing 1 followed by 0 clears the interrupt */
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
++                   ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);
++
++      /* Enable required PHY autonomous mode interrupts */
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
++
++      /* Enable i/o clamp_n for autonomous mode */
++      if (pcs_misc)
++              qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
++}
++
++static void qcom_qmp_phy_disable_autonomous_mode(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++
++      /* Disable i/o clamp_n on resume for normal mode */
++      if (pcs_misc)
++              qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
++
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
++                   ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
++
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++      /* Writing 1 followed by 0 clears the interrupt */
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++}
++
++static int __maybe_unused qcom_qmp_phy_runtime_suspend(struct device *dev)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct qmp_phy *qphy = qmp->phys[0];
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qphy->mode);
++
++      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
++      if (cfg->type != PHY_TYPE_USB3)
++              return 0;
++
++      if (!qmp->init_count) {
++              dev_vdbg(dev, "PHY not initialized, bailing out\n");
++              return 0;
++      }
++
++      qcom_qmp_phy_enable_autonomous_mode(qphy);
++
++      clk_disable_unprepare(qphy->pipe_clk);
++      clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++
++      return 0;
++}
++
++static int __maybe_unused qcom_qmp_phy_runtime_resume(struct device *dev)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct qmp_phy *qphy = qmp->phys[0];
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      int ret = 0;
++
++      dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qphy->mode);
++
++      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
++      if (cfg->type != PHY_TYPE_USB3)
++              return 0;
++
++      if (!qmp->init_count) {
++              dev_vdbg(dev, "PHY not initialized, bailing out\n");
++              return 0;
++      }
++
++      ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
++      if (ret)
++              return ret;
++
++      ret = clk_prepare_enable(qphy->pipe_clk);
++      if (ret) {
++              dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
++              clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++              return ret;
++      }
++
++      qcom_qmp_phy_disable_autonomous_mode(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int num = cfg->num_vregs;
++      int i;
++
++      qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
++      if (!qmp->vregs)
++              return -ENOMEM;
++
++      for (i = 0; i < num; i++)
++              qmp->vregs[i].supply = cfg->vreg_list[i];
++
++      return devm_regulator_bulk_get(dev, num, qmp->vregs);
++}
++
++static int qcom_qmp_phy_reset_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int i;
++
++      qmp->resets = devm_kcalloc(dev, cfg->num_resets,
++                                 sizeof(*qmp->resets), GFP_KERNEL);
++      if (!qmp->resets)
++              return -ENOMEM;
++
++      for (i = 0; i < cfg->num_resets; i++) {
++              struct reset_control *rst;
++              const char *name = cfg->reset_list[i];
++
++              rst = devm_reset_control_get_exclusive(dev, name);
++              if (IS_ERR(rst)) {
++                      dev_err(dev, "failed to get %s reset\n", name);
++                      return PTR_ERR(rst);
++              }
++              qmp->resets[i] = rst;
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_phy_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int num = cfg->num_clks;
++      int i;
++
++      qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
++      if (!qmp->clks)
++              return -ENOMEM;
++
++      for (i = 0; i < num; i++)
++              qmp->clks[i].id = cfg->clk_list[i];
++
++      return devm_clk_bulk_get(dev, num, qmp->clks);
++}
++
++static void phy_clk_release_provider(void *res)
++{
++      of_clk_del_provider(res);
++}
++
++/*
++ * Register a fixed rate pipe clock.
++ *
++ * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
++ * controls it. The <s>_pipe_clk coming out of the GCC is requested
++ * by the PHY driver for its operations.
++ * We register the <s>_pipe_clksrc here. The gcc driver takes care
++ * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
++ * Below picture shows this relationship.
++ *
++ *         +---------------+
++ *         |   PHY block   |<<---------------------------------------+
++ *         |               |                                         |
++ *         |   +-------+   |                   +-----+               |
++ *   I/P---^-->|  PLL  |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
++ *    clk  |   +-------+   |                   +-----+
++ *         +---------------+
++ */
++static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
++{
++      struct clk_fixed_rate *fixed;
++      struct clk_init_data init = { };
++      int ret;
++
++      ret = of_property_read_string(np, "clock-output-names", &init.name);
++      if (ret) {
++              dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
++              return ret;
++      }
++
++      fixed = devm_kzalloc(qmp->dev, sizeof(*fixed), GFP_KERNEL);
++      if (!fixed)
++              return -ENOMEM;
++
++      init.ops = &clk_fixed_rate_ops;
++
++      /* controllers using QMP phys use 125MHz pipe clock interface */
++      fixed->fixed_rate = 125000000;
++      fixed->hw.init = &init;
++
++      ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
++      if (ret)
++              return ret;
++
++      ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
++      if (ret)
++              return ret;
++
++      /*
++       * Roll a devm action because the clock provider is the child node, but
++       * the child node is not actually a device.
++       */
++      return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
++}
++
++/*
++ * Display Port PLL driver block diagram for branch clocks
++ *
++ *              +------------------------------+
++ *              |         DP_VCO_CLK           |
++ *              |                              |
++ *              |    +-------------------+     |
++ *              |    |   (DP PLL/VCO)    |     |
++ *              |    +---------+---------+     |
++ *              |              v               |
++ *              |   +----------+-----------+   |
++ *              |   | hsclk_divsel_clk_src |   |
++ *              |   +----------+-----------+   |
++ *              +------------------------------+
++ *                              |
++ *          +---------<---------v------------>----------+
++ *          |                                           |
++ * +--------v----------------+                          |
++ * |    dp_phy_pll_link_clk  |                          |
++ * |     link_clk            |                          |
++ * +--------+----------------+                          |
++ *          |                                           |
++ *          |                                           |
++ *          v                                           v
++ * Input to DISPCC block                                |
++ * for link clk, crypto clk                             |
++ * and interface clock                                  |
++ *                                                      |
++ *                                                      |
++ *      +--------<------------+-----------------+---<---+
++ *      |                     |                 |
++ * +----v---------+  +--------v-----+  +--------v------+
++ * | vco_divided  |  | vco_divided  |  | vco_divided   |
++ * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
++ * |              |  |              |  |               |
++ * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
++ * +-------+------+  +-----+--------+  +--------+------+
++ *         |                 |                  |
++ *         v---->----------v-------------<------v
++ *                         |
++ *              +----------+-----------------+
++ *              |   dp_phy_pll_vco_div_clk   |
++ *              +---------+------------------+
++ *                        |
++ *                        v
++ *              Input to DISPCC block
++ *              for DP pixel clock
++ *
++ */
++static int qcom_qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
++                                              struct clk_rate_request *req)
++{
++      switch (req->rate) {
++      case 1620000000UL / 2:
++      case 2700000000UL / 2:
++      /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
++              return 0;
++      default:
++              return -EINVAL;
++      }
++}
++
++static unsigned long
++qcom_qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
++{
++      const struct qmp_phy_dp_clks *dp_clks;
++      const struct qmp_phy *qphy;
++      const struct phy_configure_opts_dp *dp_opts;
++
++      dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_pixel_hw);
++      qphy = dp_clks->qphy;
++      dp_opts = &qphy->dp_opts;
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              return 1620000000UL / 2;
++      case 2700:
++              return 2700000000UL / 2;
++      case 5400:
++              return 5400000000UL / 4;
++      case 8100:
++              return 8100000000UL / 6;
++      default:
++              return 0;
++      }
++}
++
++static const struct clk_ops qcom_qmp_dp_pixel_clk_ops = {
++      .determine_rate = qcom_qmp_dp_pixel_clk_determine_rate,
++      .recalc_rate = qcom_qmp_dp_pixel_clk_recalc_rate,
++};
++
++static int qcom_qmp_dp_link_clk_determine_rate(struct clk_hw *hw,
++                                             struct clk_rate_request *req)
++{
++      switch (req->rate) {
++      case 162000000:
++      case 270000000:
++      case 540000000:
++      case 810000000:
++              return 0;
++      default:
++              return -EINVAL;
++      }
++}
++
++static unsigned long
++qcom_qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
++{
++      const struct qmp_phy_dp_clks *dp_clks;
++      const struct qmp_phy *qphy;
++      const struct phy_configure_opts_dp *dp_opts;
++
++      dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_link_hw);
++      qphy = dp_clks->qphy;
++      dp_opts = &qphy->dp_opts;
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++      case 2700:
++      case 5400:
++      case 8100:
++              return dp_opts->link_rate * 100000;
++      default:
++              return 0;
++      }
++}
++
++static const struct clk_ops qcom_qmp_dp_link_clk_ops = {
++      .determine_rate = qcom_qmp_dp_link_clk_determine_rate,
++      .recalc_rate = qcom_qmp_dp_link_clk_recalc_rate,
++};
++
++static struct clk_hw *
++qcom_qmp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *data)
++{
++      struct qmp_phy_dp_clks *dp_clks = data;
++      unsigned int idx = clkspec->args[0];
++
++      if (idx >= 2) {
++              pr_err("%s: invalid index %u\n", __func__, idx);
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (idx == 0)
++              return &dp_clks->dp_link_hw;
++
++      return &dp_clks->dp_pixel_hw;
++}
++
++static int phy_dp_clks_register(struct qcom_qmp *qmp, struct qmp_phy *qphy,
++                              struct device_node *np)
++{
++      struct clk_init_data init = { };
++      struct qmp_phy_dp_clks *dp_clks;
++      char name[64];
++      int ret;
++
++      dp_clks = devm_kzalloc(qmp->dev, sizeof(*dp_clks), GFP_KERNEL);
++      if (!dp_clks)
++              return -ENOMEM;
++
++      dp_clks->qphy = qphy;
++      qphy->dp_clks = dp_clks;
++
++      snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
++      init.ops = &qcom_qmp_dp_link_clk_ops;
++      init.name = name;
++      dp_clks->dp_link_hw.init = &init;
++      ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_link_hw);
++      if (ret)
++              return ret;
++
++      snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
++      init.ops = &qcom_qmp_dp_pixel_clk_ops;
++      init.name = name;
++      dp_clks->dp_pixel_hw.init = &init;
++      ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_pixel_hw);
++      if (ret)
++              return ret;
++
++      ret = of_clk_add_hw_provider(np, qcom_qmp_dp_clks_hw_get, dp_clks);
++      if (ret)
++              return ret;
++
++      /*
++       * Roll a devm action because the clock provider is the child node, but
++       * the child node is not actually a device.
++       */
++      return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
++}
++
++static const struct phy_ops qcom_qmp_phy_gen_ops = {
++      .init           = qcom_qmp_phy_enable,
++      .exit           = qcom_qmp_phy_disable,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static const struct phy_ops qcom_qmp_phy_dp_ops = {
++      .init           = qcom_qmp_phy_init,
++      .configure      = qcom_qmp_dp_phy_configure,
++      .power_on       = qcom_qmp_phy_power_on,
++      .calibrate      = qcom_qmp_dp_phy_calibrate,
++      .power_off      = qcom_qmp_phy_power_off,
++      .exit           = qcom_qmp_phy_exit,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static const struct phy_ops qcom_qmp_pcie_ufs_ops = {
++      .power_on       = qcom_qmp_phy_enable,
++      .power_off      = qcom_qmp_phy_disable,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static void qcom_qmp_reset_control_put(void *data)
++{
++      reset_control_put(data);
++}
++
++static
++int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id,
++                      void __iomem *serdes, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct phy *generic_phy;
++      struct qmp_phy *qphy;
++      const struct phy_ops *ops;
++      char prop_name[MAX_PROP_NAME];
++      int ret;
++
++      qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
++      if (!qphy)
++              return -ENOMEM;
++
++      qphy->cfg = cfg;
++      qphy->serdes = serdes;
++      /*
++       * Get memory resources for each phy lane:
++       * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
++       * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
++       * For single lane PHYs: pcs_misc (optional) -> 3.
++       */
++      qphy->tx = of_iomap(np, 0);
++      if (!qphy->tx)
++              return -ENOMEM;
++
++      qphy->rx = of_iomap(np, 1);
++      if (!qphy->rx)
++              return -ENOMEM;
++
++      qphy->pcs = of_iomap(np, 2);
++      if (!qphy->pcs)
++              return -ENOMEM;
++
++      /*
++       * If this is a dual-lane PHY, then there should be registers for the
++       * second lane. Some old device trees did not specify this, so fall
++       * back to old legacy behavior of assuming they can be reached at an
++       * offset from the first lane.
++       */
++      if (cfg->is_dual_lane_phy) {
++              qphy->tx2 = of_iomap(np, 3);
++              qphy->rx2 = of_iomap(np, 4);
++              if (!qphy->tx2 || !qphy->rx2) {
++                      dev_warn(dev,
++                               "Underspecified device tree, falling back to legacy register regions\n");
++
++                      /* In the old version, pcs_misc is at index 3. */
++                      qphy->pcs_misc = qphy->tx2;
++                      qphy->tx2 = qphy->tx + QMP_PHY_LEGACY_LANE_STRIDE;
++                      qphy->rx2 = qphy->rx + QMP_PHY_LEGACY_LANE_STRIDE;
++
++              } else {
++                      qphy->pcs_misc = of_iomap(np, 5);
++              }
++
++      } else {
++              qphy->pcs_misc = of_iomap(np, 3);
++      }
++
++      if (!qphy->pcs_misc)
++              dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
++
++      /*
++       * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3
++       * based phys, so they essentially have pipe clock. So,
++       * we return error in case phy is USB3 or PIPE type.
++       * Otherwise, we initialize pipe clock to NULL for
++       * all phys that don't need this.
++       */
++      snprintf(prop_name, sizeof(prop_name), "pipe%d", id);
++      qphy->pipe_clk = devm_get_clk_from_child(dev, np, prop_name);
++      if (IS_ERR(qphy->pipe_clk)) {
++              if (cfg->type == PHY_TYPE_PCIE ||
++                  cfg->type == PHY_TYPE_USB3) {
++                      ret = PTR_ERR(qphy->pipe_clk);
++                      if (ret != -EPROBE_DEFER)
++                              dev_err(dev,
++                                      "failed to get lane%d pipe_clk, %d\n",
++                                      id, ret);
++                      return ret;
++              }
++              qphy->pipe_clk = NULL;
++      }
++
++      /* Get lane reset, if any */
++      if (cfg->has_lane_rst) {
++              snprintf(prop_name, sizeof(prop_name), "lane%d", id);
++              qphy->lane_rst = of_reset_control_get_exclusive(np, prop_name);
++              if (IS_ERR(qphy->lane_rst)) {
++                      dev_err(dev, "failed to get lane%d reset\n", id);
++                      return PTR_ERR(qphy->lane_rst);
++              }
++              ret = devm_add_action_or_reset(dev, qcom_qmp_reset_control_put,
++                                             qphy->lane_rst);
++              if (ret)
++                      return ret;
++      }
++
++      if (cfg->type == PHY_TYPE_UFS || cfg->type == PHY_TYPE_PCIE)
++              ops = &qcom_qmp_pcie_ufs_ops;
++      else if (cfg->type == PHY_TYPE_DP)
++              ops = &qcom_qmp_phy_dp_ops;
++      else
++              ops = &qcom_qmp_phy_gen_ops;
++
++      generic_phy = devm_phy_create(dev, np, ops);
++      if (IS_ERR(generic_phy)) {
++              ret = PTR_ERR(generic_phy);
++              dev_err(dev, "failed to create qphy %d\n", ret);
++              return ret;
++      }
++
++      qphy->phy = generic_phy;
++      qphy->index = id;
++      qphy->qmp = qmp;
++      qmp->phys[id] = qphy;
++      phy_set_drvdata(generic_phy, qphy);
++
++      return 0;
++}
++
++static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
++      {
++              .compatible = "qcom,ipq8074-qmp-usb3-phy",
++              .data = &ipq8074_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-pcie-phy",
++              .data = &msm8996_pciephy_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-ufs-phy",
++              .data = &msm8996_ufs_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-usb3-phy",
++              .data = &msm8996_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-pcie-phy",
++              .data = &msm8998_pciephy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,ipq8074-qmp-pcie-phy",
++              .data = &ipq8074_pciephy_cfg,
++      }, {
++              .compatible = "qcom,ipq6018-qmp-pcie-phy",
++              .data = &ipq6018_pciephy_cfg,
++      }, {
++              .compatible = "qcom,ipq6018-qmp-usb3-phy",
++              .data = &ipq8074_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc7180-qmp-usb3-phy",
++              .data = &sc7180_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sc8180x-qmp-pcie-phy",
++              .data = &sc8180x_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sc8280xp-qmp-ufs-phy",
++              .data = &sm8350_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-usb3-phy",
++              .data = &sm8150_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sdm845-qhp-pcie-phy",
++              .data = &sdm845_qhp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-pcie-phy",
++              .data = &sdm845_qmp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-usb3-phy",
++              .data = &qmp_v3_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-usb3-uni-phy",
++              .data = &qmp_v3_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-usb3-phy",
++              .data = &msm8998_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm6115-qmp-ufs-phy",
++              .data = &sm6115_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm6350-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-usb3-phy",
++              .data = &sm8150_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-usb3-uni-phy",
++              .data = &sm8150_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-phy",
++              .data = &sm8250_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-uni-phy",
++              .data = &sm8250_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy",
++              .data = &sm8250_qmp_gen3x1_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-gen3x2-pcie-phy",
++              .data = &sm8250_qmp_gen3x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-ufs-phy",
++              .data = &sm8350_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-modem-pcie-phy",
++              .data = &sm8250_qmp_gen3x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdx55-qmp-pcie-phy",
++              .data = &sdx55_qmp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdx55-qmp-usb3-uni-phy",
++              .data = &sdx55_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sdx65-qmp-usb3-uni-phy",
++              .data = &sdx65_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-usb3-phy",
++              .data = &sm8350_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-usb3-uni-phy",
++              .data = &sm8350_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-gen3x1-pcie-phy",
++              .data = &sm8450_qmp_gen3x1_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-gen4x2-pcie-phy",
++              .data = &sm8450_qmp_gen4x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-ufs-phy",
++              .data = &sm8450_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-usb3-phy",
++              .data = &sm8350_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,qcm2290-qmp-usb3-phy",
++              .data = &qcm2290_usb3phy_cfg,
++      },
++      { },
++};
++MODULE_DEVICE_TABLE(of, qcom_qmp_phy_of_match_table);
++
++static const struct of_device_id qcom_qmp_combo_phy_of_match_table[] = {
++      {
++              .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
++              .data = &sc7180_usb3dpphy_cfg,
++      },
++      {
++              .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
++              .data = &sm8250_usb3dpphy_cfg,
++      },
++      {
++              .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
++              .data = &sc8180x_usb3dpphy_cfg,
++      },
++      { }
++};
++
++static const struct dev_pm_ops qcom_qmp_phy_pm_ops = {
++      SET_RUNTIME_PM_OPS(qcom_qmp_phy_runtime_suspend,
++                         qcom_qmp_phy_runtime_resume, NULL)
++};
++
++static int qcom_qmp_phy_probe(struct platform_device *pdev)
++{
++      struct qcom_qmp *qmp;
++      struct device *dev = &pdev->dev;
++      struct device_node *child;
++      struct phy_provider *phy_provider;
++      void __iomem *serdes;
++      void __iomem *usb_serdes;
++      void __iomem *dp_serdes = NULL;
++      const struct qmp_phy_combo_cfg *combo_cfg = NULL;
++      const struct qmp_phy_cfg *cfg = NULL;
++      const struct qmp_phy_cfg *usb_cfg = NULL;
++      const struct qmp_phy_cfg *dp_cfg = NULL;
++      int num, id, expected_phys;
++      int ret;
++
++      qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
++      if (!qmp)
++              return -ENOMEM;
++
++      qmp->dev = dev;
++      dev_set_drvdata(dev, qmp);
++
++      /* Get the specific init parameters of QMP phy */
++      cfg = of_device_get_match_data(dev);
++      if (!cfg) {
++              const struct of_device_id *match;
++
++              match = of_match_device(qcom_qmp_combo_phy_of_match_table, dev);
++              if (!match)
++                      return -EINVAL;
++
++              combo_cfg = match->data;
++              if (!combo_cfg)
++                      return -EINVAL;
++
++              usb_cfg = combo_cfg->usb_cfg;
++              cfg = usb_cfg; /* Setup clks and regulators */
++      }
++
++      /* per PHY serdes; usually located at base address */
++      usb_serdes = serdes = devm_platform_ioremap_resource(pdev, 0);
++      if (IS_ERR(serdes))
++              return PTR_ERR(serdes);
++
++      /* per PHY dp_com; if PHY has dp_com control block */
++      if (combo_cfg || cfg->has_phy_dp_com_ctrl) {
++              qmp->dp_com = devm_platform_ioremap_resource(pdev, 1);
++              if (IS_ERR(qmp->dp_com))
++                      return PTR_ERR(qmp->dp_com);
++      }
++
++      if (combo_cfg) {
++              /* Only two serdes for combo PHY */
++              dp_serdes = devm_platform_ioremap_resource(pdev, 2);
++              if (IS_ERR(dp_serdes))
++                      return PTR_ERR(dp_serdes);
++
++              dp_cfg = combo_cfg->dp_cfg;
++              expected_phys = 2;
++      } else {
++              expected_phys = cfg->nlanes;
++      }
++
++      mutex_init(&qmp->phy_mutex);
++
++      ret = qcom_qmp_phy_clk_init(dev, cfg);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_reset_init(dev, cfg);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_vreg_init(dev, cfg);
++      if (ret) {
++              if (ret != -EPROBE_DEFER)
++                      dev_err(dev, "failed to get regulator supplies: %d\n",
++                              ret);
++              return ret;
++      }
++
++      num = of_get_available_child_count(dev->of_node);
++      /* do we have a rogue child node ? */
++      if (num > expected_phys)
++              return -EINVAL;
++
++      qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
++      if (!qmp->phys)
++              return -ENOMEM;
++
++      pm_runtime_set_active(dev);
++      pm_runtime_enable(dev);
++      /*
++       * Prevent runtime pm from being ON by default. Users can enable
++       * it using power/control in sysfs.
++       */
++      pm_runtime_forbid(dev);
++
++      id = 0;
++      for_each_available_child_of_node(dev->of_node, child) {
++              if (of_node_name_eq(child, "dp-phy")) {
++                      cfg = dp_cfg;
++                      serdes = dp_serdes;
++              } else if (of_node_name_eq(child, "usb3-phy")) {
++                      cfg = usb_cfg;
++                      serdes = usb_serdes;
++              }
++
++              /* Create per-lane phy */
++              ret = qcom_qmp_phy_create(dev, child, id, serdes, cfg);
++              if (ret) {
++                      dev_err(dev, "failed to create lane%d phy, %d\n",
++                              id, ret);
++                      goto err_node_put;
++              }
++
++              /*
++               * Register the pipe clock provided by phy.
++               * See function description to see details of this pipe clock.
++               */
++              if (cfg->type == PHY_TYPE_USB3 || cfg->type == PHY_TYPE_PCIE) {
++                      ret = phy_pipe_clk_register(qmp, child);
++                      if (ret) {
++                              dev_err(qmp->dev,
++                                      "failed to register pipe clock source\n");
++                              goto err_node_put;
++                      }
++              } else if (cfg->type == PHY_TYPE_DP) {
++                      ret = phy_dp_clks_register(qmp, qmp->phys[id], child);
++                      if (ret) {
++                              dev_err(qmp->dev,
++                                      "failed to register DP clock source\n");
++                              goto err_node_put;
++                      }
++              }
++              id++;
++      }
++
++      phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
++      if (!IS_ERR(phy_provider))
++              dev_info(dev, "Registered Qcom-QMP phy\n");
++      else
++              pm_runtime_disable(dev);
++
++      return PTR_ERR_OR_ZERO(phy_provider);
++
++err_node_put:
++      pm_runtime_disable(dev);
++      of_node_put(child);
++      return ret;
++}
++
++static struct platform_driver qcom_qmp_phy_driver = {
++      .probe          = qcom_qmp_phy_probe,
++      .driver = {
++              .name   = "qcom-qmp-phy",
++              .pm     = &qcom_qmp_phy_pm_ops,
++              .of_match_table = qcom_qmp_phy_of_match_table,
++      },
++};
++
++module_platform_driver(qcom_qmp_phy_driver);
++
++MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
++MODULE_DESCRIPTION("Qualcomm QMP PHY driver");
++MODULE_LICENSE("GPL v2");
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+new file mode 100644
+index 000000000000..c7309e981bfb
+--- /dev/null
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+@@ -0,0 +1,6350 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++
++#include <dt-bindings/phy/phy.h>
++
++#include "phy-qcom-qmp.h"
++
++/* QPHY_SW_RESET bit */
++#define SW_RESET                              BIT(0)
++/* QPHY_POWER_DOWN_CONTROL */
++#define SW_PWRDN                              BIT(0)
++#define REFCLK_DRV_DSBL                               BIT(1)
++/* QPHY_START_CONTROL bits */
++#define SERDES_START                          BIT(0)
++#define PCS_START                             BIT(1)
++#define PLL_READY_GATE_EN                     BIT(3)
++/* QPHY_PCS_STATUS bit */
++#define PHYSTATUS                             BIT(6)
++#define PHYSTATUS_4_20                                BIT(7)
++/* QPHY_PCS_READY_STATUS & QPHY_COM_PCS_READY_STATUS bit */
++#define PCS_READY                             BIT(0)
++
++/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
++/* DP PHY soft reset */
++#define SW_DPPHY_RESET                                BIT(0)
++/* mux to select DP PHY reset control, 0:HW control, 1: software reset */
++#define SW_DPPHY_RESET_MUX                    BIT(1)
++/* USB3 PHY soft reset */
++#define SW_USB3PHY_RESET                      BIT(2)
++/* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
++#define SW_USB3PHY_RESET_MUX                  BIT(3)
++
++/* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
++#define USB3_MODE                             BIT(0) /* enables USB3 mode */
++#define DP_MODE                                       BIT(1) /* enables DP mode */
++
++/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
++#define ARCVR_DTCT_EN                         BIT(0)
++#define ALFPS_DTCT_EN                         BIT(1)
++#define ARCVR_DTCT_EVENT_SEL                  BIT(4)
++
++/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
++#define IRQ_CLEAR                             BIT(0)
++
++/* QPHY_PCS_LFPS_RXTERM_IRQ_STATUS register bits */
++#define RCVR_DETECT                           BIT(0)
++
++/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
++#define CLAMP_EN                              BIT(0) /* enables i/o clamp_n */
++
++#define PHY_INIT_COMPLETE_TIMEOUT             10000
++#define POWER_DOWN_DELAY_US_MIN                       10
++#define POWER_DOWN_DELAY_US_MAX                       11
++
++#define MAX_PROP_NAME                         32
++
++/* Define the assumed distance between lanes for underspecified device trees. */
++#define QMP_PHY_LEGACY_LANE_STRIDE            0x400
++
++struct qmp_phy_init_tbl {
++      unsigned int offset;
++      unsigned int val;
++      /*
++       * register part of layout ?
++       * if yes, then offset gives index in the reg-layout
++       */
++      bool in_layout;
++      /*
++       * mask of lanes for which this register is written
++       * for cases when second lane needs different values
++       */
++      u8 lane_mask;
++};
++
++#define QMP_PHY_INIT_CFG(o, v)                \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .lane_mask = 0xff,      \
++      }
++
++#define QMP_PHY_INIT_CFG_L(o, v)      \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .in_layout = true,      \
++              .lane_mask = 0xff,      \
++      }
++
++#define QMP_PHY_INIT_CFG_LANE(o, v, l)        \
++      {                               \
++              .offset = o,            \
++              .val = v,               \
++              .lane_mask = l,         \
++      }
++
++/* set of registers with offsets different per-PHY */
++enum qphy_reg_layout {
++      /* Common block control registers */
++      QPHY_COM_SW_RESET,
++      QPHY_COM_POWER_DOWN_CONTROL,
++      QPHY_COM_START_CONTROL,
++      QPHY_COM_PCS_READY_STATUS,
++      /* PCS registers */
++      QPHY_PLL_LOCK_CHK_DLY_TIME,
++      QPHY_FLL_CNTRL1,
++      QPHY_FLL_CNTRL2,
++      QPHY_FLL_CNT_VAL_L,
++      QPHY_FLL_CNT_VAL_H_TOL,
++      QPHY_FLL_MAN_CODE,
++      QPHY_SW_RESET,
++      QPHY_START_CTRL,
++      QPHY_PCS_READY_STATUS,
++      QPHY_PCS_STATUS,
++      QPHY_PCS_AUTONOMOUS_MODE_CTRL,
++      QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
++      QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
++      QPHY_PCS_POWER_DOWN_CONTROL,
++      /* PCS_MISC registers */
++      QPHY_PCS_MISC_TYPEC_CTRL,
++      /* Keep last to ensure regs_layout arrays are properly initialized */
++      QPHY_LAYOUT_SIZE
++};
++
++static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x168,
++};
++
++static const unsigned int ipq_pciephy_gen3_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                         = 0x00,
++      [QPHY_START_CTRL]                       = 0x44,
++      [QPHY_PCS_STATUS]                       = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]           = 0x40,
++};
++
++static const unsigned int pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_COM_SW_RESET]             = 0x400,
++      [QPHY_COM_POWER_DOWN_CONTROL]   = 0x404,
++      [QPHY_COM_START_CONTROL]        = 0x408,
++      [QPHY_COM_PCS_READY_STATUS]     = 0x448,
++      [QPHY_PLL_LOCK_CHK_DLY_TIME]    = 0xa8,
++      [QPHY_FLL_CNTRL1]               = 0xc4,
++      [QPHY_FLL_CNTRL2]               = 0xc8,
++      [QPHY_FLL_CNT_VAL_L]            = 0xcc,
++      [QPHY_FLL_CNT_VAL_H_TOL]        = 0xd0,
++      [QPHY_FLL_MAN_CODE]             = 0xd4,
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++};
++
++static const unsigned int usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_FLL_CNTRL1]               = 0xc0,
++      [QPHY_FLL_CNTRL2]               = 0xc4,
++      [QPHY_FLL_CNT_VAL_L]            = 0xc8,
++      [QPHY_FLL_CNT_VAL_H_TOL]        = 0xcc,
++      [QPHY_FLL_MAN_CODE]             = 0xd0,
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x17c,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d4,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0d8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178,
++};
++
++static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0dc,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
++};
++
++static const unsigned int sdm845_qmp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x174,
++};
++
++static const unsigned int sdm845_qhp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_STATUS]               = 0x2ac,
++};
++
++static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x308,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x314,
++};
++
++static const unsigned int qmp_v4_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x608,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x614,
++};
++
++static const unsigned int sm8350_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x1008,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x1014,
++};
++
++static const unsigned int qcm2290_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x04,
++      [QPHY_START_CTRL]               = 0x08,
++      [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0xd8,
++      [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0xdc,
++      [QPHY_PCS_STATUS]               = 0x174,
++      [QPHY_PCS_MISC_TYPEC_CTRL]      = 0x00,
++};
++
++static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x160,
++};
++
++static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = 0x00,
++      [QPHY_PCS_READY_STATUS]         = 0x168,
++};
++
++static const unsigned int sm8250_pcie_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_SW_RESET]                 = 0x00,
++      [QPHY_START_CTRL]               = 0x44,
++      [QPHY_PCS_STATUS]               = 0x14,
++      [QPHY_PCS_POWER_DOWN_CONTROL]   = 0x40,
++};
++
++static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
++      [QPHY_START_CTRL]               = QPHY_V4_PCS_UFS_PHY_START,
++      [QPHY_PCS_READY_STATUS]         = QPHY_V4_PCS_UFS_READY_STATUS,
++      [QPHY_SW_RESET]                 = QPHY_V4_PCS_UFS_SW_RESET,
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      /* PLL and Loop filter settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      /* SSC settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x0),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x40),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x19),
++};
++
++static const struct qmp_phy_init_tbl msm8996_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_RX_IDLE_DTCT_CNTRL, 0x4c),
++      QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++
++      QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x05),
++
++      QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x05),
++      QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG4, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG1, 0xa3),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0x0e),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x7e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x15),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x40),
++};
++
++static const struct qmp_phy_init_tbl msm8998_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x99),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02),
++};
++
++static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x04),
++      /* PLL and Loop filter settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      /* SSC settings */
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xbb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++};
++
++static const struct qmp_phy_init_tbl msm8996_usb3_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL2, 0x03),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_H_TOL, 0x42),
++      QMP_PHY_INIT_CFG_L(QPHY_FLL_MAN_CODE, 0x85),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG2, 0x08),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x29),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x53),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_TX0_LANE_MODE_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_TX0_RCV_DETECT_LVL_2, 0x12),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_GAIN, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0x61),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_LOW, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH2, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH3, 0xd3),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH4, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_LOW, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_RX0_DFE_EN_TIMER, 0x04),
++};
++
++static const struct qmp_phy_init_tbl ipq6018_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL1, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(PCS_COM_G12S1_TXDEEMPH_M3P5DB, 0x10),
++      QMP_PHY_INIT_CFG(PCS_COM_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_RX_DCC_CAL_CONFIG, 0x01),
++      QMP_PHY_INIT_CFG(PCS_COM_EQ_CONFIG5, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
++      QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
++      QMP_PHY_INIT_CFG(PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++      QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG1, 0x11),
++      QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_POST, 0x58),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0xf),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0xf),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xa),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x3),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0xD),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xD04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0xb),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x6),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET, 0x2),
++      QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_TX_EMP_POST1_LVL, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_TX_SLEW_CNTL, 0x0a),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x1),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x0),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x4),
++};
++
++static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x4),
++      QMP_PHY_INIT_CFG(QPHY_OSC_DTCT_ACTIONS, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB, 0x0),
++      QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x40),
++      QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x73),
++      QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_LVL, 0x99),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0xe),
++      QMP_PHY_INIT_CFG_L(QPHY_SW_RESET, 0x0),
++      QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x007),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_EP_DIV, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x33),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x7e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x15),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_01, 0x59),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x71),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x40),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE, 0x04),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xbb),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG4, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_CONFIG2, 0x52),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG2, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG4, 0x1a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG5, 0x06),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MISC_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SYSCLK_EN_SEL, 0x27),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE2, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BIAS_EN_CKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CLK_ENABLE1, 0xb0),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP1_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP2_MODE0, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_RESTRIM_CTRL2, 0x05),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VCO_TUNE_MAP, 0x10),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CLK_SELECT, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_HSCLK_SEL1, 0x30),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORECLK_DIV, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORE_CLK_EN, 0x73),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CMN_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_SVS_MODE_CLK_SEL, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VREGCLK_DIV1, 0x22),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_VREGCLK_DIV2, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BGV_TRIM, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_COM_BG_CTRL, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL0, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_TAP_EN, 0x0d),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_TX_BAND_MODE, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_LANE_MODE, 0x1a),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PARALLEL_RATE, 0x2f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE0, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE1, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CML_CTRL_MODE2, 0x1b),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PREAMP_CTRL_MODE1, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PREAMP_CTRL_MODE2, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE0, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE1, 0x31),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_MIXER_CTRL_MODE2, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_THRESH_DFE, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CGA_THRESH_DFE, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXENGINE_EN0, 0x12),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_TRAIN_TIME, 0x25),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_CTLE_DFE_OVRLP_TIME, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_REFRESH_TIME, 0x05),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_ENABLE_TIME, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_VGA_GAIN, 0x26),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DFE_GAIN, 0x12),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EQ_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_OFFSET_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PRE_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EQ_INTVAL, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_EDAC_INITVAL, 0x28),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_INITB0, 0x7f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_INITB1, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RCVRDONE_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RXEQ_CTRL, 0x70),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE0, 0x8b),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_FO_GAIN_MODE2, 0x0a),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_GAIN_MODE2, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_UCDR_SO_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_BAND, 0x02),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE0, 0x5c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE1, 0x3e),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RCVR_PATH1_MODE2, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_ENABLES, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_CNTRL, 0xa0),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_SIGDET_DEGLITCH_CNTRL, 0x08),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DCC_GAIN, 0x01),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_EN_SIGNAL, 0xc3),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_PSM_RX_EN_CAL, 0x00),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_MISC_CNTRL0, 0xbc),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_TS0_TIMER, 0x7f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DLL_HIGHDATARATE, 0x15),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_DRVR_CTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RX_RESETCODE_OFFSET, 0x04),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_VGA_INITVAL, 0x20),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RSM_START, 0x01),
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_rx_tbl[] = {
++};
++
++static const struct qmp_phy_init_tbl sdm845_qhp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG, 0x3f),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_PCS_TX_RX_CONFIG, 0x50),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_MAIN_V0_M3P5DB, 0x19),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_POST_V0_M3P5DB, 0x07),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_MAIN_V0_M6DB, 0x17),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_TXMGN_POST_V0_M6DB, 0x09),
++      QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG5, 0x9f),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_rbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x6f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr2[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr3[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_dp_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRANSCEIVER_BIAS_EN, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_VMODE_CTRL1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_INTERFACE_SELECT, 0x3d),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_CLKBUF_ENABLE, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RESET_TSYNC_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRAN_DRVR_EMP_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_BAND, 0x4),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_POL_INV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_DRV_LVL, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_EMP_POST1_LVL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++};
++
++static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
++      /* FLL settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb5),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4c),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x64),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
++      QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
++      QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
++};
++
++static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_RX_PWM_GEAR_BAND, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_DRV_LVL, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
++      QMP_PHY_INIT_CFG(QPHY_RX_SYM_RESYNC_CTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
++      QMP_PHY_INIT_CFG(QPHY_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
++};
++
++static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_CTRL2, 0x6e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SYM_RESYNC_CTRL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_CTRL1, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_MIN_HIBERN8_TIME, 0x9a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_INITVAL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
++      QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x43),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05),
++};
++
++static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x8a),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
++
++};
++
++static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x94),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_pcs_tbl[] = {
++      /* Lock Det settings */
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x95),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xef),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x60),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x60),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x40, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x54, 2),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0xff, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f, 2),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff, 2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x97),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0xb8),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_CTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORE_CLK_EN, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_rbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x6f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr2[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x8c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr3[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
++};
++
++static const struct qmp_phy_init_tbl qmp_v4_dp_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_VMODE_CTRL1, 0x40),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_INTERFACE_SELECT, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_CLKBUF_ENABLE, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RESET_TSYNC_EN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_INTERFACE_MODE, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_BAND, 0x4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_POL_INV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_DRV_LVL, 0x2a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_EMP_POST1_LVL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x5),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x6e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x6e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x39),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x39),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x01),
++};
++
++static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x35),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x30),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x12),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE, 0x33),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x05),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG2, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x08),
++};
++
++static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x26),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x048),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x46),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_CFG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x50),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MISC1, 0x88),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTERNAL_DIG_CORECLK_DIV, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MODE, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_DC_LEVEL_CTRL, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x56),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x4b),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x22),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_3, 0x13),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_VMODE_CTRL1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_PI_QEC_CTRL, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_FO_GAIN_RATE2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_UCDR_PI_CONTROLS, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_AUX_DATA_TCOARSE_TFINE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_3, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_VGA_CAL_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B1, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B2, 0x5a),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B3, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B4, 0x37),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B0, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B1, 0xf9),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B3, 0xce),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B4, 0x62),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B0, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B1, 0x7d),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B3, 0xcf),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B4, 0xd6),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_PHPRE_CTRL, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_MARG_COARSE_CTRL2, 0x12),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG2, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG4, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG5, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_EQ_CONFIG1, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G3_RXEQEVAL_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_RXEQEVAL_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG2, 0x01),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_SW_CTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_MX_CTRL2, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sdx65_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0b),
++};
++
++static const struct qmp_phy_init_tbl sdx65_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_ENABLES, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
++
++      /* Rate B */
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_PLL_CNTL, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_RX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x35),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_5, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xbb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbb),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3d, 1),
++      QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3c, 2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xd2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x13),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_EN_TIMER, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VTH_CODE, 0x10),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x7b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xe4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_ENABLES, 0x00),
++};
++
++static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
++      QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_INITVAL, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x01),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x00),
++};
++
++static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE0, 0x24),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE2_MODE1, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE1, 0xb4),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x68),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0xaa),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0xab),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_BUF_ENABLE, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x75),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x04),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xff),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xd8),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xdc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0x5c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_TX_ADAPT_POST_THRESH, 0xf0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x09),
++      QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x77),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RATE_SLEW_CNTRL1, 0x0b),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x05),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG2, 0x0f),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_serdes_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x97),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x46),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_CFG, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0xd0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0x55),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE0, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x04),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MISC1, 0x88),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORE_CLK_EN, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_CONFIG, 0x06),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MODE, 0x14),
++      QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_DC_LEVEL_CTRL, 0x0f),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_tx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_1, 0x05),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_2, 0xf6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_rx_tbl[] = {
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_PI_CONTROLS, 0x16),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B1, 0xcc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B2, 0x12),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B3, 0xcc),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B5, 0x4a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B6, 0x29),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B0, 0xc5),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B1, 0xad),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B2, 0xb6),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B3, 0xc0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B4, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B5, 0xfb),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B6, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B0, 0xc7),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B1, 0xef),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B2, 0xbf),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B3, 0xa0),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B4, 0x81),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B5, 0xde),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B6, 0x7f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_PHPRE_CTRL, 0x20),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_0_1, 0x3f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_2_3, 0x37),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_3, 0x05),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE3, 0x1f),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE210, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE210, 0x1f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE210, 0x1f),
++
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE2, 0x0c),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE3, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_VGA_CAL_MAN_VAL, 0x0a),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_IDAC_SAOFFSET, 0x10),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_DAC_ENABLE1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_GM_CAL, 0x0f),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH1, 0x00),
++      QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH2, 0x1f),
++};
++
++/* Register names should be validated, they might be different for this PHY */
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG2, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG3, 0x22),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_G3S2_PRE_GAIN, 0x2e),
++      QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x99),
++};
++
++static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_EQ_CONFIG1, 0x16),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_RX_MARGINING_CONFIG3, 0x28),
++      QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_PRE_GAIN, 0x2e),
++};
++
++struct qmp_phy;
++
++/* struct qmp_phy_cfg - per-PHY initialization config */
++struct qmp_phy_cfg {
++      /* phy-type - PCIE/UFS/USB */
++      unsigned int type;
++      /* number of lanes provided by phy */
++      int nlanes;
++
++      /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
++      const struct qmp_phy_init_tbl *serdes_tbl;
++      int serdes_tbl_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_sec;
++      int serdes_tbl_num_sec;
++      const struct qmp_phy_init_tbl *tx_tbl;
++      int tx_tbl_num;
++      const struct qmp_phy_init_tbl *tx_tbl_sec;
++      int tx_tbl_num_sec;
++      const struct qmp_phy_init_tbl *rx_tbl;
++      int rx_tbl_num;
++      const struct qmp_phy_init_tbl *rx_tbl_sec;
++      int rx_tbl_num_sec;
++      const struct qmp_phy_init_tbl *pcs_tbl;
++      int pcs_tbl_num;
++      const struct qmp_phy_init_tbl *pcs_tbl_sec;
++      int pcs_tbl_num_sec;
++      const struct qmp_phy_init_tbl *pcs_misc_tbl;
++      int pcs_misc_tbl_num;
++      const struct qmp_phy_init_tbl *pcs_misc_tbl_sec;
++      int pcs_misc_tbl_num_sec;
++
++      /* Init sequence for DP PHY block link rates */
++      const struct qmp_phy_init_tbl *serdes_tbl_rbr;
++      int serdes_tbl_rbr_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr;
++      int serdes_tbl_hbr_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr2;
++      int serdes_tbl_hbr2_num;
++      const struct qmp_phy_init_tbl *serdes_tbl_hbr3;
++      int serdes_tbl_hbr3_num;
++
++      /* DP PHY callbacks */
++      int (*configure_dp_phy)(struct qmp_phy *qphy);
++      void (*configure_dp_tx)(struct qmp_phy *qphy);
++      int (*calibrate_dp_phy)(struct qmp_phy *qphy);
++      void (*dp_aux_init)(struct qmp_phy *qphy);
++
++      /* clock ids to be requested */
++      const char * const *clk_list;
++      int num_clks;
++      /* resets to be requested */
++      const char * const *reset_list;
++      int num_resets;
++      /* regulators to be requested */
++      const char * const *vreg_list;
++      int num_vregs;
++
++      /* array of registers with different offsets */
++      const unsigned int *regs;
++
++      unsigned int start_ctrl;
++      unsigned int pwrdn_ctrl;
++      unsigned int mask_com_pcs_ready;
++      /* bit offset of PHYSTATUS in QPHY_PCS_STATUS register */
++      unsigned int phy_status;
++
++      /* true, if PHY has a separate PHY_COM control block */
++      bool has_phy_com_ctrl;
++      /* true, if PHY has a reset for individual lanes */
++      bool has_lane_rst;
++      /* true, if PHY needs delay after POWER_DOWN */
++      bool has_pwrdn_delay;
++      /* power_down delay in usec */
++      int pwrdn_delay_min;
++      int pwrdn_delay_max;
++
++      /* true, if PHY has a separate DP_COM control block */
++      bool has_phy_dp_com_ctrl;
++      /* true, if PHY has secondary tx/rx lanes to be configured */
++      bool is_dual_lane_phy;
++
++      /* true, if PCS block has no separate SW_RESET register */
++      bool no_pcs_sw_reset;
++};
++
++struct qmp_phy_combo_cfg {
++      const struct qmp_phy_cfg *usb_cfg;
++      const struct qmp_phy_cfg *dp_cfg;
++};
++
++/**
++ * struct qmp_phy - per-lane phy descriptor
++ *
++ * @phy: generic phy
++ * @cfg: phy specific configuration
++ * @serdes: iomapped memory space for phy's serdes (i.e. PLL)
++ * @tx: iomapped memory space for lane's tx
++ * @rx: iomapped memory space for lane's rx
++ * @pcs: iomapped memory space for lane's pcs
++ * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
++ * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
++ * @pcs_misc: iomapped memory space for lane's pcs_misc
++ * @pipe_clk: pipe clock
++ * @index: lane index
++ * @qmp: QMP phy to which this lane belongs
++ * @lane_rst: lane's reset controller
++ * @mode: current PHY mode
++ * @dp_aux_cfg: Display port aux config
++ * @dp_opts: Display port optional config
++ * @dp_clks: Display port clocks
++ */
++struct qmp_phy {
++      struct phy *phy;
++      const struct qmp_phy_cfg *cfg;
++      void __iomem *serdes;
++      void __iomem *tx;
++      void __iomem *rx;
++      void __iomem *pcs;
++      void __iomem *tx2;
++      void __iomem *rx2;
++      void __iomem *pcs_misc;
++      struct clk *pipe_clk;
++      unsigned int index;
++      struct qcom_qmp *qmp;
++      struct reset_control *lane_rst;
++      enum phy_mode mode;
++      unsigned int dp_aux_cfg;
++      struct phy_configure_opts_dp dp_opts;
++      struct qmp_phy_dp_clks *dp_clks;
++};
++
++struct qmp_phy_dp_clks {
++      struct qmp_phy *qphy;
++      struct clk_hw dp_link_hw;
++      struct clk_hw dp_pixel_hw;
++};
++
++/**
++ * struct qcom_qmp - structure holding QMP phy block attributes
++ *
++ * @dev: device
++ * @dp_com: iomapped memory space for phy's dp_com control block
++ *
++ * @clks: array of clocks required by phy
++ * @resets: array of resets required by phy
++ * @vregs: regulator supplies bulk data
++ *
++ * @phys: array of per-lane phy descriptors
++ * @phy_mutex: mutex lock for PHY common block initialization
++ * @init_count: phy common block initialization count
++ * @ufs_reset: optional UFS PHY reset handle
++ */
++struct qcom_qmp {
++      struct device *dev;
++      void __iomem *dp_com;
++
++      struct clk_bulk_data *clks;
++      struct reset_control **resets;
++      struct regulator_bulk_data *vregs;
++
++      struct qmp_phy **phys;
++
++      struct mutex phy_mutex;
++      int init_count;
++
++      struct reset_control *ufs_reset;
++};
++
++static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy);
++static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy);
++static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy);
++static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy);
++
++static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy);
++static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy);
++static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy);
++static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy);
++
++static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
++{
++      u32 reg;
++
++      reg = readl(base + offset);
++      reg |= val;
++      writel(reg, base + offset);
++
++      /* ensure that above write is through */
++      readl(base + offset);
++}
++
++static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
++{
++      u32 reg;
++
++      reg = readl(base + offset);
++      reg &= ~val;
++      writel(reg, base + offset);
++
++      /* ensure that above write is through */
++      readl(base + offset);
++}
++
++/* list of clocks required by phy */
++static const char * const msm8996_phy_clk_l[] = {
++      "aux", "cfg_ahb", "ref",
++};
++
++static const char * const msm8996_ufs_phy_clk_l[] = {
++      "ref",
++};
++
++static const char * const qmp_v3_phy_clk_l[] = {
++      "aux", "cfg_ahb", "ref", "com_aux",
++};
++
++static const char * const sdm845_pciephy_clk_l[] = {
++      "aux", "cfg_ahb", "ref", "refgen",
++};
++
++static const char * const qmp_v4_phy_clk_l[] = {
++      "aux", "ref_clk_src", "ref", "com_aux",
++};
++
++/* the primary usb3 phy on sm8250 doesn't have a ref clock */
++static const char * const qmp_v4_sm8250_usbphy_clk_l[] = {
++      "aux", "ref_clk_src", "com_aux"
++};
++
++static const char * const sm8450_ufs_phy_clk_l[] = {
++      "qref", "ref", "ref_aux",
++};
++
++static const char * const sdm845_ufs_phy_clk_l[] = {
++      "ref", "ref_aux",
++};
++
++/* usb3 phy on sdx55 doesn't have com_aux clock */
++static const char * const qmp_v4_sdx55_usbphy_clk_l[] = {
++      "aux", "cfg_ahb", "ref"
++};
++
++static const char * const qcm2290_usb3phy_clk_l[] = {
++      "cfg_ahb", "ref", "com_aux",
++};
++
++/* list of resets */
++static const char * const msm8996_pciephy_reset_l[] = {
++      "phy", "common", "cfg",
++};
++
++static const char * const msm8996_usb3phy_reset_l[] = {
++      "phy", "common",
++};
++
++static const char * const sc7180_usb3phy_reset_l[] = {
++      "phy",
++};
++
++static const char * const qcm2290_usb3phy_reset_l[] = {
++      "phy_phy", "phy",
++};
++
++static const char * const sdm845_pciephy_reset_l[] = {
++      "phy",
++};
++
++/* list of regulators */
++static const char * const qmp_phy_vreg_l[] = {
++      "vdda-phy", "vdda-pll",
++};
++
++static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq8074_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq8074_usb3_serdes_tbl),
++      .tx_tbl                 = msm8996_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_usb3_tx_tbl),
++      .rx_tbl                 = ipq8074_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq8074_usb3_rx_tbl),
++      .pcs_tbl                = ipq8074_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq8074_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++};
++
++static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 3,
++
++      .serdes_tbl             = msm8996_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_pcie_serdes_tbl),
++      .tx_tbl                 = msm8996_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_pcie_tx_tbl),
++      .rx_tbl                 = msm8996_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_pcie_rx_tbl),
++      .pcs_tbl                = msm8996_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8996_pcie_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | PLL_READY_GATE_EN,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .mask_com_pcs_ready     = PCS_READY,
++      .phy_status             = PHYSTATUS,
++
++      .has_phy_com_ctrl       = true,
++      .has_lane_rst           = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg msm8996_ufs_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8996_ufs_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_ufs_serdes_tbl),
++      .tx_tbl                 = msm8996_ufs_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_ufs_tx_tbl),
++      .rx_tbl                 = msm8996_ufs_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_ufs_rx_tbl),
++
++      .clk_list               = msm8996_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_ufs_phy_clk_l),
++
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++
++      .regs                   = msm8996_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8996_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8996_usb3_serdes_tbl),
++      .tx_tbl                 = msm8996_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8996_usb3_tx_tbl),
++      .rx_tbl                 = msm8996_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8996_usb3_rx_tbl),
++      .pcs_tbl                = msm8996_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8996_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++};
++
++static const char * const ipq8074_pciephy_clk_l[] = {
++      "aux", "cfg_ahb",
++};
++/* list of resets */
++static const char * const ipq8074_pciephy_reset_l[] = {
++      "phy", "common",
++};
++
++static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq8074_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq8074_pcie_serdes_tbl),
++      .tx_tbl                 = ipq8074_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_tx_tbl),
++      .rx_tbl                 = ipq8074_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_rx_tbl),
++      .pcs_tbl                = ipq8074_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq8074_pcie_pcs_tbl),
++      .clk_list               = ipq8074_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(ipq8074_pciephy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = NULL,
++      .num_vregs              = 0,
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_phy_com_ctrl       = false,
++      .has_lane_rst           = false,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = ipq6018_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(ipq6018_pcie_serdes_tbl),
++      .tx_tbl                 = ipq6018_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(ipq6018_pcie_tx_tbl),
++      .rx_tbl                 = ipq6018_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(ipq6018_pcie_rx_tbl),
++      .pcs_tbl                = ipq6018_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(ipq6018_pcie_pcs_tbl),
++      .clk_list               = ipq8074_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(ipq8074_pciephy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = NULL,
++      .num_vregs              = 0,
++      .regs                   = ipq_pciephy_gen3_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++
++      .has_phy_com_ctrl       = false,
++      .has_lane_rst           = false,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sdm845_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sdm845_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sdm845_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sdm845_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sdm845_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sdm845_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_qmp_pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdm845_qhp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sdm845_qhp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_qhp_pcie_serdes_tbl),
++      .tx_tbl                 = sdm845_qhp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_qhp_pcie_tx_tbl),
++      .rx_tbl                 = sdm845_qhp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_qhp_pcie_rx_tbl),
++      .pcs_tbl                = sdm845_qhp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_qhp_pcie_pcs_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_qhp_pciephy_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sm8250_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
++      .serdes_tbl_sec         = sm8250_qmp_gen3x1_pcie_serdes_tbl,
++      .serdes_tbl_num_sec     = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_serdes_tbl),
++      .tx_tbl                 = sm8250_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sm8250_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
++      .rx_tbl_sec             = sm8250_qmp_gen3x1_pcie_rx_tbl,
++      .rx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_rx_tbl),
++      .pcs_tbl                = sm8250_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
++      .pcs_tbl_sec            = sm8250_qmp_gen3x1_pcie_pcs_tbl,
++      .pcs_tbl_num_sec                = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8250_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
++      .pcs_misc_tbl_sec               = sm8250_qmp_gen3x1_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num_sec   = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sm8250_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sm8250_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
++      .tx_tbl_sec             = sm8250_qmp_gen3x2_pcie_tx_tbl,
++      .tx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_tx_tbl),
++      .rx_tbl                 = sm8250_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
++      .rx_tbl_sec             = sm8250_qmp_gen3x2_pcie_rx_tbl,
++      .rx_tbl_num_sec         = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_rx_tbl),
++      .pcs_tbl                = sm8250_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
++      .pcs_tbl_sec            = sm8250_qmp_gen3x2_pcie_pcs_tbl,
++      .pcs_tbl_num_sec                = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8250_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
++      .pcs_misc_tbl_sec               = sm8250_qmp_gen3x2_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num_sec   = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc7180_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v3_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v3_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v3_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v3_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v3_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v3_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v3_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v3_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v3_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sc7180_usb3dpphy_cfg = {
++      .usb_cfg                = &sc7180_usb3phy_cfg,
++      .dp_cfg                 = &sc7180_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v3_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v3_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = qmp_v3_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = qmp_v3_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qmp_v3_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = qmp_v3_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qmp_v3_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sdm845_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
++      .tx_tbl                 = sdm845_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
++      .rx_tbl                 = sdm845_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
++      .pcs_tbl                = sdm845_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sdm845_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm6115_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm6115_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
++      .rx_tbl                 = sm6115_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
++      .pcs_tbl                = sm6115_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm6115_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++
++      .is_dual_lane_phy       = false,
++      .no_pcs_sw_reset        = true,
++};
++
++static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
++      .type                   = PHY_TYPE_PCIE,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8998_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8998_pcie_serdes_tbl),
++      .tx_tbl                 = msm8998_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8998_pcie_tx_tbl),
++      .rx_tbl                 = msm8998_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8998_pcie_rx_tbl),
++      .pcs_tbl                = msm8998_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8998_pcie_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = ipq8074_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = pciephy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++};
++
++static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = msm8998_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl),
++      .tx_tbl                 = msm8998_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(msm8998_usb3_tx_tbl),
++      .rx_tbl                 = msm8998_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
++      .pcs_tbl                = msm8998_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
++      .clk_list               = msm8996_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8150_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8150_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8150_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8150_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8150_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_usb3_tx_tbl),
++      .rx_tbl                 = sm8150_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_usb3_rx_tbl),
++      .pcs_tbl                = sm8150_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sc8180x_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sc8180x_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sc8180x_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sc8180x_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sc8180x_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sc8180x_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sc8180x_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sc8180x_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sc8180x_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v4_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v4_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v4_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v4_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v4_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v4_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v3_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v3_phy_clk_l),
++      .reset_list             = sc7180_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v3_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sc8180x_usb3dpphy_cfg = {
++      .usb_cfg                = &sm8150_usb3phy_cfg,
++      .dp_cfg                 = &sc8180x_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8150_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8150_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8150_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8150_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8150_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8150_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8250_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_usb3_tx_tbl),
++      .rx_tbl                 = sm8250_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_usb3_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_sm8250_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8250_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8250_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8250_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8250_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8250_dpphy_cfg = {
++      .type                   = PHY_TYPE_DP,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qmp_v4_dp_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
++      .tx_tbl                 = qmp_v4_dp_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
++
++      .serdes_tbl_rbr         = qmp_v4_dp_serdes_tbl_rbr,
++      .serdes_tbl_rbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
++      .serdes_tbl_hbr         = qmp_v4_dp_serdes_tbl_hbr,
++      .serdes_tbl_hbr_num     = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
++      .serdes_tbl_hbr2        = qmp_v4_dp_serdes_tbl_hbr2,
++      .serdes_tbl_hbr2_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
++      .serdes_tbl_hbr3        = qmp_v4_dp_serdes_tbl_hbr3,
++      .serdes_tbl_hbr3_num    = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
++
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++
++      .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
++      .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
++      .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
++      .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
++};
++
++static const struct qmp_phy_combo_cfg sm8250_usb3dpphy_cfg = {
++      .usb_cfg                = &sm8250_usb3phy_cfg,
++      .dp_cfg                 = &sm8250_dpphy_cfg,
++};
++
++static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sdx55_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx55_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sdx55_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx55_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8250_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_sdx55_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sdx55_qmp_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sdx55_qmp_pcie_serdes_tbl),
++      .tx_tbl                 = sdx55_qmp_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx55_qmp_pcie_tx_tbl),
++      .rx_tbl                 = sdx55_qmp_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx55_qmp_pcie_rx_tbl),
++      .pcs_tbl                = sdx55_qmp_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sdx55_qmp_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sdx55_qmp_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sdx55_qmp_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = PCS_START | SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS_4_20,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sdx65_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sdx65_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sdx65_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sdx65_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_sdx55_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8350_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8350_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8350_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8350_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8350_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
++      .clk_list               = sdm845_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_serdes_tbl),
++      .tx_tbl                 = sm8350_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_usb3_tx_tbl),
++      .rx_tbl                 = sm8350_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_usb3_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_pcs_tbl),
++      .clk_list               = qmp_v4_sm8250_usbphy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qmp_v4_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++
++      .has_phy_dp_com_ctrl    = true,
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = sm8150_usb3_uniphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
++      .tx_tbl                 = sm8350_usb3_uniphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_usb3_uniphy_tx_tbl),
++      .rx_tbl                 = sm8350_usb3_uniphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_usb3_uniphy_rx_tbl),
++      .pcs_tbl                = sm8350_usb3_uniphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl),
++      .clk_list               = qmp_v4_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qmp_v4_phy_clk_l),
++      .reset_list             = msm8996_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8350_usb3_uniphy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
++      .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
++};
++
++static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
++      .type                   = PHY_TYPE_UFS,
++      .nlanes                 = 2,
++
++      .serdes_tbl             = sm8350_ufsphy_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
++      .tx_tbl                 = sm8350_ufsphy_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
++      .rx_tbl                 = sm8350_ufsphy_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
++      .pcs_tbl                = sm8350_ufsphy_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
++      .clk_list               = sm8450_ufs_phy_clk_l,
++      .num_clks               = ARRAY_SIZE(sm8450_ufs_phy_clk_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8150_ufsphy_regs_layout,
++
++      .start_ctrl             = SERDES_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static const struct qmp_phy_cfg sm8450_qmp_gen3x1_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 1,
++
++      .serdes_tbl             = sm8450_qmp_gen3x1_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_serdes_tbl),
++      .tx_tbl                 = sm8450_qmp_gen3x1_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_tx_tbl),
++      .rx_tbl                 = sm8450_qmp_gen3x1_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_rx_tbl),
++      .pcs_tbl                = sm8450_qmp_gen3x1_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8450_qmp_gen3x1_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS,
++
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg sm8450_qmp_gen4x2_pciephy_cfg = {
++      .type = PHY_TYPE_PCIE,
++      .nlanes = 2,
++
++      .serdes_tbl             = sm8450_qmp_gen4x2_pcie_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_serdes_tbl),
++      .tx_tbl                 = sm8450_qmp_gen4x2_pcie_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_tx_tbl),
++      .rx_tbl                 = sm8450_qmp_gen4x2_pcie_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_rx_tbl),
++      .pcs_tbl                = sm8450_qmp_gen4x2_pcie_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_pcs_tbl),
++      .pcs_misc_tbl           = sm8450_qmp_gen4x2_pcie_pcs_misc_tbl,
++      .pcs_misc_tbl_num       = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_pcs_misc_tbl),
++      .clk_list               = sdm845_pciephy_clk_l,
++      .num_clks               = ARRAY_SIZE(sdm845_pciephy_clk_l),
++      .reset_list             = sdm845_pciephy_reset_l,
++      .num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = sm8250_pcie_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
++      .phy_status             = PHYSTATUS_4_20,
++
++      .is_dual_lane_phy       = true,
++      .has_pwrdn_delay        = true,
++      .pwrdn_delay_min        = 995,          /* us */
++      .pwrdn_delay_max        = 1005,         /* us */
++};
++
++static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
++      .type                   = PHY_TYPE_USB3,
++      .nlanes                 = 1,
++
++      .serdes_tbl             = qcm2290_usb3_serdes_tbl,
++      .serdes_tbl_num         = ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
++      .tx_tbl                 = qcm2290_usb3_tx_tbl,
++      .tx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_tx_tbl),
++      .rx_tbl                 = qcm2290_usb3_rx_tbl,
++      .rx_tbl_num             = ARRAY_SIZE(qcm2290_usb3_rx_tbl),
++      .pcs_tbl                = qcm2290_usb3_pcs_tbl,
++      .pcs_tbl_num            = ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
++      .clk_list               = qcm2290_usb3phy_clk_l,
++      .num_clks               = ARRAY_SIZE(qcm2290_usb3phy_clk_l),
++      .reset_list             = qcm2290_usb3phy_reset_l,
++      .num_resets             = ARRAY_SIZE(qcm2290_usb3phy_reset_l),
++      .vreg_list              = qmp_phy_vreg_l,
++      .num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
++      .regs                   = qcm2290_usb3phy_regs_layout,
++
++      .start_ctrl             = SERDES_START | PCS_START,
++      .pwrdn_ctrl             = SW_PWRDN,
++      .phy_status             = PHYSTATUS,
++
++      .is_dual_lane_phy       = true,
++};
++
++static void qcom_qmp_phy_configure_lane(void __iomem *base,
++                                      const unsigned int *regs,
++                                      const struct qmp_phy_init_tbl tbl[],
++                                      int num,
++                                      u8 lane_mask)
++{
++      int i;
++      const struct qmp_phy_init_tbl *t = tbl;
++
++      if (!t)
++              return;
++
++      for (i = 0; i < num; i++, t++) {
++              if (!(t->lane_mask & lane_mask))
++                      continue;
++
++              if (t->in_layout)
++                      writel(t->val, base + regs[t->offset]);
++              else
++                      writel(t->val, base + t->offset);
++      }
++}
++
++static void qcom_qmp_phy_configure(void __iomem *base,
++                                 const unsigned int *regs,
++                                 const struct qmp_phy_init_tbl tbl[],
++                                 int num)
++{
++      qcom_qmp_phy_configure_lane(base, regs, tbl, num, 0xff);
++}
++
++static int qcom_qmp_phy_serdes_init(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
++      int serdes_tbl_num = cfg->serdes_tbl_num;
++      int ret;
++
++      qcom_qmp_phy_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num);
++      if (cfg->serdes_tbl_sec)
++              qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl_sec,
++                                     cfg->serdes_tbl_num_sec);
++
++      if (cfg->type == PHY_TYPE_DP) {
++              switch (dp_opts->link_rate) {
++              case 1620:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_rbr,
++                                             cfg->serdes_tbl_rbr_num);
++                      break;
++              case 2700:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr,
++                                             cfg->serdes_tbl_hbr_num);
++                      break;
++              case 5400:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr2,
++                                             cfg->serdes_tbl_hbr2_num);
++                      break;
++              case 8100:
++                      qcom_qmp_phy_configure(serdes, cfg->regs,
++                                             cfg->serdes_tbl_hbr3,
++                                             cfg->serdes_tbl_hbr3_num);
++                      break;
++              default:
++                      /* Other link rates aren't supported */
++                      return -EINVAL;
++              }
++      }
++
++
++      if (cfg->has_phy_com_ctrl) {
++              void __iomem *status;
++              unsigned int mask, val;
++
++              qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET], SW_RESET);
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
++                           SERDES_START | PCS_START);
++
++              status = serdes + cfg->regs[QPHY_COM_PCS_READY_STATUS];
++              mask = cfg->mask_com_pcs_ready;
++
++              ret = readl_poll_timeout(status, val, (val & mask), 10,
++                                       PHY_INIT_COMPLETE_TIMEOUT);
++              if (ret) {
++                      dev_err(qmp->dev,
++                              "phy common block init timed-out\n");
++                      return ret;
++              }
++      }
++
++      return 0;
++}
++
++static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy)
++{
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      /* Turn on BIAS current for PHY/PLL */
++      writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX |
++             QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL,
++             qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_LANE_0_1_PWRDN |
++             DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN |
++             DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(QSERDES_V3_COM_BIAS_EN |
++             QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN |
++             QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL |
++             QSERDES_V3_COM_CLKBUF_RX_DRIVE_L,
++             qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0x24, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
++      writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
++      writel(0xbb, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
++      qphy->dp_aux_cfg = 0;
++
++      writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
++             PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
++             PHY_AUX_REQ_ERR_MASK,
++             qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
++}
++
++static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = {
++      { 0x00, 0x0c, 0x15, 0x1a },
++      { 0x02, 0x0e, 0x16, 0xff },
++      { 0x02, 0x11, 0xff, 0xff },
++      { 0x04, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_voltage_swing_hbr3_hbr2[4][4] = {
++      { 0x02, 0x12, 0x16, 0x1a },
++      { 0x09, 0x19, 0x1f, 0xff },
++      { 0x10, 0x1f, 0xff, 0xff },
++      { 0x1f, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = {
++      { 0x00, 0x0c, 0x14, 0x19 },
++      { 0x00, 0x0b, 0x12, 0xff },
++      { 0x00, 0x0b, 0xff, 0xff },
++      { 0x04, 0xff, 0xff, 0xff }
++};
++
++static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
++      { 0x08, 0x0f, 0x16, 0x1f },
++      { 0x11, 0x1e, 0x1f, 0xff },
++      { 0x19, 0x1f, 0xff, 0xff },
++      { 0x1f, 0xff, 0xff, 0xff }
++};
++
++static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy,
++              unsigned int drv_lvl_reg, unsigned int emp_post_reg)
++{
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      unsigned int v_level = 0, p_level = 0;
++      u8 voltage_swing_cfg, pre_emphasis_cfg;
++      int i;
++
++      for (i = 0; i < dp_opts->lanes; i++) {
++              v_level = max(v_level, dp_opts->voltage[i]);
++              p_level = max(p_level, dp_opts->pre[i]);
++      }
++
++      if (dp_opts->link_rate <= 2700) {
++              voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
++              pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
++      } else {
++              voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr3_hbr2[v_level][p_level];
++              pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr3_hbr2[v_level][p_level];
++      }
++
++      /* TODO: Move check to config check */
++      if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
++              return -EINVAL;
++
++      /* Enable MUX to use Cursor values from these registers */
++      voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
++      pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
++
++      writel(voltage_swing_cfg, qphy->tx + drv_lvl_reg);
++      writel(pre_emphasis_cfg, qphy->tx + emp_post_reg);
++      writel(voltage_swing_cfg, qphy->tx2 + drv_lvl_reg);
++      writel(pre_emphasis_cfg, qphy->tx2 + emp_post_reg);
++
++      return 0;
++}
++
++static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)
++{
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 bias_en, drvr_en;
++
++      if (qcom_qmp_phy_configure_dp_swing(qphy,
++                              QSERDES_V3_TX_TX_DRV_LVL,
++                              QSERDES_V3_TX_TX_EMP_POST1_LVL) < 0)
++              return;
++
++      if (dp_opts->lanes == 1) {
++              bias_en = 0x3e;
++              drvr_en = 0x13;
++      } else {
++              bias_en = 0x3f;
++              drvr_en = 0x10;
++      }
++
++      writel(drvr_en, qphy->tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
++      writel(bias_en, qphy->tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
++      writel(drvr_en, qphy->tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
++      writel(bias_en, qphy->tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
++}
++
++static bool qcom_qmp_phy_configure_dp_mode(struct qmp_phy *qphy)
++{
++      u32 val;
++      bool reverse = false;
++
++      val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++            DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN;
++
++      /*
++       * TODO: Assume orientation is CC1 for now and two lanes, need to
++       * use type-c connector to understand orientation and lanes.
++       *
++       * Otherwise val changes to be like below if this code understood
++       * the orientation of the type-c cable.
++       *
++       * if (lane_cnt == 4 || orientation == ORIENTATION_CC2)
++       *      val |= DP_PHY_PD_CTL_LANE_0_1_PWRDN;
++       * if (lane_cnt == 4 || orientation == ORIENTATION_CC1)
++       *      val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
++       * if (orientation == ORIENTATION_CC2)
++       *      writel(0x4c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
++       */
++      val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
++      writel(val, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      writel(0x5c, qphy->pcs + QSERDES_DP_PHY_MODE);
++
++      return reverse;
++}
++
++static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 phy_vco_div, status;
++      unsigned long pixel_freq;
++
++      qcom_qmp_phy_configure_dp_mode(qphy);
++
++      writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
++      writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              phy_vco_div = 0x1;
++              pixel_freq = 1620000000UL / 2;
++              break;
++      case 2700:
++              phy_vco_div = 0x1;
++              pixel_freq = 2700000000UL / 2;
++              break;
++      case 5400:
++              phy_vco_div = 0x2;
++              pixel_freq = 5400000000UL / 4;
++              break;
++      case 8100:
++              phy_vco_div = 0x0;
++              pixel_freq = 8100000000UL / 6;
++              break;
++      default:
++              /* Other link rates aren't supported */
++              return -EINVAL;
++      }
++      writel(phy_vco_div, qphy->pcs + QSERDES_V3_DP_PHY_VCO_DIV);
++
++      clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
++      clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
++
++      writel(0x04, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      writel(0x20, qphy->serdes + QSERDES_V3_COM_RESETSM_CNTRL);
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V3_COM_C_READY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
++      udelay(2000);
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      return readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000);
++}
++
++/*
++ * We need to calibrate the aux setting here as many times
++ * as the caller tries
++ */
++static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy)
++{
++      static const u8 cfg1_settings[] = { 0x13, 0x23, 0x1d };
++      u8 val;
++
++      qphy->dp_aux_cfg++;
++      qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
++      val = cfg1_settings[qphy->dp_aux_cfg];
++
++      writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++
++      return 0;
++}
++
++static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy)
++{
++      writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
++             DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
++             qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++
++      /* Turn on BIAS current for PHY/PLL */
++      writel(0x17, qphy->serdes + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
++
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++      writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
++      writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
++      writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
++      writel(0xb7, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
++      writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
++      qphy->dp_aux_cfg = 0;
++
++      writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
++             PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
++             PHY_AUX_REQ_ERR_MASK,
++             qphy->pcs + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
++}
++
++static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy)
++{
++      /* Program default values before writing proper values */
++      writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
++      writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
++
++      writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++      writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++
++      qcom_qmp_phy_configure_dp_swing(qphy,
++                      QSERDES_V4_TX_TX_DRV_LVL,
++                      QSERDES_V4_TX_TX_EMP_POST1_LVL);
++}
++
++static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
++      const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
++      u32 phy_vco_div, status;
++      unsigned long pixel_freq;
++      u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
++      bool reverse;
++
++      writel(0x0f, qphy->pcs + QSERDES_V4_DP_PHY_CFG_1);
++
++      reverse = qcom_qmp_phy_configure_dp_mode(qphy);
++
++      writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++      writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
++
++      writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL);
++      writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL);
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              phy_vco_div = 0x1;
++              pixel_freq = 1620000000UL / 2;
++              break;
++      case 2700:
++              phy_vco_div = 0x1;
++              pixel_freq = 2700000000UL / 2;
++              break;
++      case 5400:
++              phy_vco_div = 0x2;
++              pixel_freq = 5400000000UL / 4;
++              break;
++      case 8100:
++              phy_vco_div = 0x0;
++              pixel_freq = 8100000000UL / 6;
++              break;
++      default:
++              /* Other link rates aren't supported */
++              return -EINVAL;
++      }
++      writel(phy_vco_div, qphy->pcs + QSERDES_V4_DP_PHY_VCO_DIV);
++
++      clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
++      clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
++
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
++      writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      writel(0x20, qphy->serdes + QSERDES_V4_COM_RESETSM_CNTRL);
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_C_READY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(0)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      /*
++       * At least for 7nm DP PHY this has to be done after enabling link
++       * clock.
++       */
++
++      if (dp_opts->lanes == 1) {
++              bias0_en = reverse ? 0x3e : 0x15;
++              bias1_en = reverse ? 0x15 : 0x3e;
++              drvr0_en = reverse ? 0x13 : 0x10;
++              drvr1_en = reverse ? 0x10 : 0x13;
++      } else if (dp_opts->lanes == 2) {
++              bias0_en = reverse ? 0x3f : 0x15;
++              bias1_en = reverse ? 0x15 : 0x3f;
++              drvr0_en = 0x10;
++              drvr1_en = 0x10;
++      } else {
++              bias0_en = 0x3f;
++              bias1_en = 0x3f;
++              drvr0_en = 0x10;
++              drvr1_en = 0x10;
++      }
++
++      writel(drvr0_en, qphy->tx + QSERDES_V4_TX_HIGHZ_DRVR_EN);
++      writel(bias0_en, qphy->tx + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
++      writel(drvr1_en, qphy->tx2 + QSERDES_V4_TX_HIGHZ_DRVR_EN);
++      writel(bias1_en, qphy->tx2 + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
++
++      writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
++      udelay(2000);
++      writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
++
++      if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
++                      status,
++                      ((status & BIT(1)) > 0),
++                      500,
++                      10000))
++              return -ETIMEDOUT;
++
++      writel(0x0a, qphy->tx + QSERDES_V4_TX_TX_POL_INV);
++      writel(0x0a, qphy->tx2 + QSERDES_V4_TX_TX_POL_INV);
++
++      writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
++      writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
++
++      writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++      writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
++
++      return 0;
++}
++
++/*
++ * We need to calibrate the aux setting here as many times
++ * as the caller tries
++ */
++static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy)
++{
++      static const u8 cfg1_settings[] = { 0x20, 0x13, 0x23, 0x1d };
++      u8 val;
++
++      qphy->dp_aux_cfg++;
++      qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
++      val = cfg1_settings[qphy->dp_aux_cfg];
++
++      writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
++
++      return 0;
++}
++
++static int qcom_qmp_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
++{
++      const struct phy_configure_opts_dp *dp_opts = &opts->dp;
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      memcpy(&qphy->dp_opts, dp_opts, sizeof(*dp_opts));
++      if (qphy->dp_opts.set_voltages) {
++              cfg->configure_dp_tx(qphy);
++              qphy->dp_opts.set_voltages = 0;
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_dp_phy_calibrate(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      if (cfg->calibrate_dp_phy)
++              return cfg->calibrate_dp_phy(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_com_init(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *dp_com = qmp->dp_com;
++      int ret, i;
++
++      mutex_lock(&qmp->phy_mutex);
++      if (qmp->init_count++) {
++              mutex_unlock(&qmp->phy_mutex);
++              return 0;
++      }
++
++      /* turn on regulator supplies */
++      ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
++      if (ret) {
++              dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
++              goto err_unlock;
++      }
++
++      for (i = 0; i < cfg->num_resets; i++) {
++              ret = reset_control_assert(qmp->resets[i]);
++              if (ret) {
++                      dev_err(qmp->dev, "%s reset assert failed\n",
++                              cfg->reset_list[i]);
++                      goto err_disable_regulators;
++              }
++      }
++
++      for (i = cfg->num_resets - 1; i >= 0; i--) {
++              ret = reset_control_deassert(qmp->resets[i]);
++              if (ret) {
++                      dev_err(qmp->dev, "%s reset deassert failed\n",
++                              qphy->cfg->reset_list[i]);
++                      goto err_assert_reset;
++              }
++      }
++
++      ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
++      if (ret)
++              goto err_assert_reset;
++
++      if (cfg->has_phy_dp_com_ctrl) {
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_POWER_DOWN_CTRL,
++                           SW_PWRDN);
++              /* override hardware control for reset of qmp phy */
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
++                           SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
++                           SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
++
++              /* Default type-c orientation, i.e CC1 */
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_TYPEC_CTRL, 0x02);
++
++              qphy_setbits(dp_com, QPHY_V3_DP_COM_PHY_MODE_CTRL,
++                           USB3_MODE | DP_MODE);
++
++              /* bring both QMP USB and QMP DP PHYs PCS block out of reset */
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
++                           SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
++                           SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
++
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_SWI_CTRL, 0x03);
++              qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
++      }
++
++      if (cfg->has_phy_com_ctrl) {
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
++                           SW_PWRDN);
++      } else {
++              if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
++                      qphy_setbits(pcs,
++                                      cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++                                      cfg->pwrdn_ctrl);
++              else
++                      qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL,
++                                      cfg->pwrdn_ctrl);
++      }
++
++      mutex_unlock(&qmp->phy_mutex);
++
++      return 0;
++
++err_assert_reset:
++      while (++i < cfg->num_resets)
++              reset_control_assert(qmp->resets[i]);
++err_disable_regulators:
++      regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
++err_unlock:
++      mutex_unlock(&qmp->phy_mutex);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_com_exit(struct qmp_phy *qphy)
++{
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *serdes = qphy->serdes;
++      int i = cfg->num_resets;
++
++      mutex_lock(&qmp->phy_mutex);
++      if (--qmp->init_count) {
++              mutex_unlock(&qmp->phy_mutex);
++              return 0;
++      }
++
++      reset_control_assert(qmp->ufs_reset);
++      if (cfg->has_phy_com_ctrl) {
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
++                           SERDES_START | PCS_START);
++              qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET],
++                           SW_RESET);
++              qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
++                           SW_PWRDN);
++      }
++
++      while (--i >= 0)
++              reset_control_assert(qmp->resets[i]);
++
++      clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++
++      regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
++
++      mutex_unlock(&qmp->phy_mutex);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_init(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      int ret;
++      dev_vdbg(qmp->dev, "Initializing QMP phy\n");
++
++      if (cfg->no_pcs_sw_reset) {
++              /*
++               * Get UFS reset, which is delayed until now to avoid a
++               * circular dependency where UFS needs its PHY, but the PHY
++               * needs this UFS reset.
++               */
++              if (!qmp->ufs_reset) {
++                      qmp->ufs_reset =
++                              devm_reset_control_get_exclusive(qmp->dev,
++                                                               "ufsphy");
++
++                      if (IS_ERR(qmp->ufs_reset)) {
++                              ret = PTR_ERR(qmp->ufs_reset);
++                              dev_err(qmp->dev,
++                                      "failed to get UFS reset: %d\n",
++                                      ret);
++
++                              qmp->ufs_reset = NULL;
++                              return ret;
++                      }
++              }
++
++              ret = reset_control_assert(qmp->ufs_reset);
++              if (ret)
++                      return ret;
++      }
++
++      ret = qcom_qmp_phy_com_init(qphy);
++      if (ret)
++              return ret;
++
++      if (cfg->type == PHY_TYPE_DP)
++              cfg->dp_aux_init(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_power_on(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      struct qcom_qmp *qmp = qphy->qmp;
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *tx = qphy->tx;
++      void __iomem *rx = qphy->rx;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++      void __iomem *status;
++      unsigned int mask, val, ready;
++      int ret;
++
++      qcom_qmp_phy_serdes_init(qphy);
++
++      if (cfg->has_lane_rst) {
++              ret = reset_control_deassert(qphy->lane_rst);
++              if (ret) {
++                      dev_err(qmp->dev, "lane%d reset deassert failed\n",
++                              qphy->index);
++                      return ret;
++              }
++      }
++
++      ret = clk_prepare_enable(qphy->pipe_clk);
++      if (ret) {
++              dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
++              goto err_reset_lane;
++      }
++
++      /* Tx, Rx, and PCS configurations */
++      qcom_qmp_phy_configure_lane(tx, cfg->regs,
++                                  cfg->tx_tbl, cfg->tx_tbl_num, 1);
++      if (cfg->tx_tbl_sec)
++              qcom_qmp_phy_configure_lane(tx, cfg->regs, cfg->tx_tbl_sec,
++                                          cfg->tx_tbl_num_sec, 1);
++
++      /* Configuration for other LANE for USB-DP combo PHY */
++      if (cfg->is_dual_lane_phy) {
++              qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
++                                          cfg->tx_tbl, cfg->tx_tbl_num, 2);
++              if (cfg->tx_tbl_sec)
++                      qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
++                                                  cfg->tx_tbl_sec,
++                                                  cfg->tx_tbl_num_sec, 2);
++      }
++
++      /* Configure special DP tx tunings */
++      if (cfg->type == PHY_TYPE_DP)
++              cfg->configure_dp_tx(qphy);
++
++      qcom_qmp_phy_configure_lane(rx, cfg->regs,
++                                  cfg->rx_tbl, cfg->rx_tbl_num, 1);
++      if (cfg->rx_tbl_sec)
++              qcom_qmp_phy_configure_lane(rx, cfg->regs,
++                                          cfg->rx_tbl_sec, cfg->rx_tbl_num_sec, 1);
++
++      if (cfg->is_dual_lane_phy) {
++              qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
++                                          cfg->rx_tbl, cfg->rx_tbl_num, 2);
++              if (cfg->rx_tbl_sec)
++                      qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
++                                                  cfg->rx_tbl_sec,
++                                                  cfg->rx_tbl_num_sec, 2);
++      }
++
++      /* Configure link rate, swing, etc. */
++      if (cfg->type == PHY_TYPE_DP) {
++              cfg->configure_dp_phy(qphy);
++      } else {
++              qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
++              if (cfg->pcs_tbl_sec)
++                      qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl_sec,
++                                             cfg->pcs_tbl_num_sec);
++      }
++
++      ret = reset_control_deassert(qmp->ufs_reset);
++      if (ret)
++              goto err_disable_pipe_clk;
++
++      qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl,
++                             cfg->pcs_misc_tbl_num);
++      if (cfg->pcs_misc_tbl_sec)
++              qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl_sec,
++                                     cfg->pcs_misc_tbl_num_sec);
++
++      /*
++       * Pull out PHY from POWER DOWN state.
++       * This is active low enable signal to power-down PHY.
++       */
++      if(cfg->type == PHY_TYPE_PCIE)
++              qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
++
++      if (cfg->has_pwrdn_delay)
++              usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
++
++      if (cfg->type != PHY_TYPE_DP) {
++              /* Pull PHY out of reset state */
++              if (!cfg->no_pcs_sw_reset)
++                      qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
++              /* start SerDes and Phy-Coding-Sublayer */
++              qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
++
++              if (cfg->type == PHY_TYPE_UFS) {
++                      status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
++                      mask = PCS_READY;
++                      ready = PCS_READY;
++              } else {
++                      status = pcs + cfg->regs[QPHY_PCS_STATUS];
++                      mask = cfg->phy_status;
++                      ready = 0;
++              }
++
++              ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
++                                       PHY_INIT_COMPLETE_TIMEOUT);
++              if (ret) {
++                      dev_err(qmp->dev, "phy initialization timed-out\n");
++                      goto err_disable_pipe_clk;
++              }
++      }
++      return 0;
++
++err_disable_pipe_clk:
++      clk_disable_unprepare(qphy->pipe_clk);
++err_reset_lane:
++      if (cfg->has_lane_rst)
++              reset_control_assert(qphy->lane_rst);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_power_off(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      clk_disable_unprepare(qphy->pipe_clk);
++
++      if (cfg->type == PHY_TYPE_DP) {
++              /* Assert DP PHY power down */
++              writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
++      } else {
++              /* PHY reset */
++              if (!cfg->no_pcs_sw_reset)
++                      qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
++
++              /* stop SerDes and Phy-Coding-Sublayer */
++              qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
++
++              /* Put PHY into POWER DOWN state: active low */
++              if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) {
++                      qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++                                   cfg->pwrdn_ctrl);
++              } else {
++                      qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL,
++                                      cfg->pwrdn_ctrl);
++              }
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_phy_exit(struct phy *phy)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      if (cfg->has_lane_rst)
++              reset_control_assert(qphy->lane_rst);
++
++      qcom_qmp_phy_com_exit(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_enable(struct phy *phy)
++{
++      int ret;
++
++      ret = qcom_qmp_phy_init(phy);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_power_on(phy);
++      if (ret)
++              qcom_qmp_phy_exit(phy);
++
++      return ret;
++}
++
++static int qcom_qmp_phy_disable(struct phy *phy)
++{
++      int ret;
++
++      ret = qcom_qmp_phy_power_off(phy);
++      if (ret)
++              return ret;
++      return qcom_qmp_phy_exit(phy);
++}
++
++static int qcom_qmp_phy_set_mode(struct phy *phy,
++                               enum phy_mode mode, int submode)
++{
++      struct qmp_phy *qphy = phy_get_drvdata(phy);
++
++      qphy->mode = mode;
++
++      return 0;
++}
++
++static void qcom_qmp_phy_enable_autonomous_mode(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++      u32 intr_mask;
++
++      if (qphy->mode == PHY_MODE_USB_HOST_SS ||
++          qphy->mode == PHY_MODE_USB_DEVICE_SS)
++              intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
++      else
++              intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
++
++      /* Clear any pending interrupts status */
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++      /* Writing 1 followed by 0 clears the interrupt */
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
++                   ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);
++
++      /* Enable required PHY autonomous mode interrupts */
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
++
++      /* Enable i/o clamp_n for autonomous mode */
++      if (pcs_misc)
++              qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
++}
++
++static void qcom_qmp_phy_disable_autonomous_mode(struct qmp_phy *qphy)
++{
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      void __iomem *pcs = qphy->pcs;
++      void __iomem *pcs_misc = qphy->pcs_misc;
++
++      /* Disable i/o clamp_n on resume for normal mode */
++      if (pcs_misc)
++              qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
++
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
++                   ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
++
++      qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++      /* Writing 1 followed by 0 clears the interrupt */
++      qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
++}
++
++static int __maybe_unused qcom_qmp_phy_runtime_suspend(struct device *dev)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct qmp_phy *qphy = qmp->phys[0];
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++
++      dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qphy->mode);
++
++      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
++      if (cfg->type != PHY_TYPE_USB3)
++              return 0;
++
++      if (!qmp->init_count) {
++              dev_vdbg(dev, "PHY not initialized, bailing out\n");
++              return 0;
++      }
++
++      qcom_qmp_phy_enable_autonomous_mode(qphy);
++
++      clk_disable_unprepare(qphy->pipe_clk);
++      clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++
++      return 0;
++}
++
++static int __maybe_unused qcom_qmp_phy_runtime_resume(struct device *dev)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct qmp_phy *qphy = qmp->phys[0];
++      const struct qmp_phy_cfg *cfg = qphy->cfg;
++      int ret = 0;
++
++      dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qphy->mode);
++
++      /* Supported only for USB3 PHY and luckily USB3 is the first phy */
++      if (cfg->type != PHY_TYPE_USB3)
++              return 0;
++
++      if (!qmp->init_count) {
++              dev_vdbg(dev, "PHY not initialized, bailing out\n");
++              return 0;
++      }
++
++      ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
++      if (ret)
++              return ret;
++
++      ret = clk_prepare_enable(qphy->pipe_clk);
++      if (ret) {
++              dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
++              clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
++              return ret;
++      }
++
++      qcom_qmp_phy_disable_autonomous_mode(qphy);
++
++      return 0;
++}
++
++static int qcom_qmp_phy_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int num = cfg->num_vregs;
++      int i;
++
++      qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
++      if (!qmp->vregs)
++              return -ENOMEM;
++
++      for (i = 0; i < num; i++)
++              qmp->vregs[i].supply = cfg->vreg_list[i];
++
++      return devm_regulator_bulk_get(dev, num, qmp->vregs);
++}
++
++static int qcom_qmp_phy_reset_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int i;
++
++      qmp->resets = devm_kcalloc(dev, cfg->num_resets,
++                                 sizeof(*qmp->resets), GFP_KERNEL);
++      if (!qmp->resets)
++              return -ENOMEM;
++
++      for (i = 0; i < cfg->num_resets; i++) {
++              struct reset_control *rst;
++              const char *name = cfg->reset_list[i];
++
++              rst = devm_reset_control_get_exclusive(dev, name);
++              if (IS_ERR(rst)) {
++                      dev_err(dev, "failed to get %s reset\n", name);
++                      return PTR_ERR(rst);
++              }
++              qmp->resets[i] = rst;
++      }
++
++      return 0;
++}
++
++static int qcom_qmp_phy_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      int num = cfg->num_clks;
++      int i;
++
++      qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
++      if (!qmp->clks)
++              return -ENOMEM;
++
++      for (i = 0; i < num; i++)
++              qmp->clks[i].id = cfg->clk_list[i];
++
++      return devm_clk_bulk_get(dev, num, qmp->clks);
++}
++
++static void phy_clk_release_provider(void *res)
++{
++      of_clk_del_provider(res);
++}
++
++/*
++ * Register a fixed rate pipe clock.
++ *
++ * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
++ * controls it. The <s>_pipe_clk coming out of the GCC is requested
++ * by the PHY driver for its operations.
++ * We register the <s>_pipe_clksrc here. The gcc driver takes care
++ * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
++ * Below picture shows this relationship.
++ *
++ *         +---------------+
++ *         |   PHY block   |<<---------------------------------------+
++ *         |               |                                         |
++ *         |   +-------+   |                   +-----+               |
++ *   I/P---^-->|  PLL  |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
++ *    clk  |   +-------+   |                   +-----+
++ *         +---------------+
++ */
++static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
++{
++      struct clk_fixed_rate *fixed;
++      struct clk_init_data init = { };
++      int ret;
++
++      ret = of_property_read_string(np, "clock-output-names", &init.name);
++      if (ret) {
++              dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
++              return ret;
++      }
++
++      fixed = devm_kzalloc(qmp->dev, sizeof(*fixed), GFP_KERNEL);
++      if (!fixed)
++              return -ENOMEM;
++
++      init.ops = &clk_fixed_rate_ops;
++
++      /* controllers using QMP phys use 125MHz pipe clock interface */
++      fixed->fixed_rate = 125000000;
++      fixed->hw.init = &init;
++
++      ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
++      if (ret)
++              return ret;
++
++      ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
++      if (ret)
++              return ret;
++
++      /*
++       * Roll a devm action because the clock provider is the child node, but
++       * the child node is not actually a device.
++       */
++      return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
++}
++
++/*
++ * Display Port PLL driver block diagram for branch clocks
++ *
++ *              +------------------------------+
++ *              |         DP_VCO_CLK           |
++ *              |                              |
++ *              |    +-------------------+     |
++ *              |    |   (DP PLL/VCO)    |     |
++ *              |    +---------+---------+     |
++ *              |              v               |
++ *              |   +----------+-----------+   |
++ *              |   | hsclk_divsel_clk_src |   |
++ *              |   +----------+-----------+   |
++ *              +------------------------------+
++ *                              |
++ *          +---------<---------v------------>----------+
++ *          |                                           |
++ * +--------v----------------+                          |
++ * |    dp_phy_pll_link_clk  |                          |
++ * |     link_clk            |                          |
++ * +--------+----------------+                          |
++ *          |                                           |
++ *          |                                           |
++ *          v                                           v
++ * Input to DISPCC block                                |
++ * for link clk, crypto clk                             |
++ * and interface clock                                  |
++ *                                                      |
++ *                                                      |
++ *      +--------<------------+-----------------+---<---+
++ *      |                     |                 |
++ * +----v---------+  +--------v-----+  +--------v------+
++ * | vco_divided  |  | vco_divided  |  | vco_divided   |
++ * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
++ * |              |  |              |  |               |
++ * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
++ * +-------+------+  +-----+--------+  +--------+------+
++ *         |                 |                  |
++ *         v---->----------v-------------<------v
++ *                         |
++ *              +----------+-----------------+
++ *              |   dp_phy_pll_vco_div_clk   |
++ *              +---------+------------------+
++ *                        |
++ *                        v
++ *              Input to DISPCC block
++ *              for DP pixel clock
++ *
++ */
++static int qcom_qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
++                                              struct clk_rate_request *req)
++{
++      switch (req->rate) {
++      case 1620000000UL / 2:
++      case 2700000000UL / 2:
++      /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
++              return 0;
++      default:
++              return -EINVAL;
++      }
++}
++
++static unsigned long
++qcom_qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
++{
++      const struct qmp_phy_dp_clks *dp_clks;
++      const struct qmp_phy *qphy;
++      const struct phy_configure_opts_dp *dp_opts;
++
++      dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_pixel_hw);
++      qphy = dp_clks->qphy;
++      dp_opts = &qphy->dp_opts;
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++              return 1620000000UL / 2;
++      case 2700:
++              return 2700000000UL / 2;
++      case 5400:
++              return 5400000000UL / 4;
++      case 8100:
++              return 8100000000UL / 6;
++      default:
++              return 0;
++      }
++}
++
++static const struct clk_ops qcom_qmp_dp_pixel_clk_ops = {
++      .determine_rate = qcom_qmp_dp_pixel_clk_determine_rate,
++      .recalc_rate = qcom_qmp_dp_pixel_clk_recalc_rate,
++};
++
++static int qcom_qmp_dp_link_clk_determine_rate(struct clk_hw *hw,
++                                             struct clk_rate_request *req)
++{
++      switch (req->rate) {
++      case 162000000:
++      case 270000000:
++      case 540000000:
++      case 810000000:
++              return 0;
++      default:
++              return -EINVAL;
++      }
++}
++
++static unsigned long
++qcom_qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
++{
++      const struct qmp_phy_dp_clks *dp_clks;
++      const struct qmp_phy *qphy;
++      const struct phy_configure_opts_dp *dp_opts;
++
++      dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_link_hw);
++      qphy = dp_clks->qphy;
++      dp_opts = &qphy->dp_opts;
++
++      switch (dp_opts->link_rate) {
++      case 1620:
++      case 2700:
++      case 5400:
++      case 8100:
++              return dp_opts->link_rate * 100000;
++      default:
++              return 0;
++      }
++}
++
++static const struct clk_ops qcom_qmp_dp_link_clk_ops = {
++      .determine_rate = qcom_qmp_dp_link_clk_determine_rate,
++      .recalc_rate = qcom_qmp_dp_link_clk_recalc_rate,
++};
++
++static struct clk_hw *
++qcom_qmp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *data)
++{
++      struct qmp_phy_dp_clks *dp_clks = data;
++      unsigned int idx = clkspec->args[0];
++
++      if (idx >= 2) {
++              pr_err("%s: invalid index %u\n", __func__, idx);
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (idx == 0)
++              return &dp_clks->dp_link_hw;
++
++      return &dp_clks->dp_pixel_hw;
++}
++
++static int phy_dp_clks_register(struct qcom_qmp *qmp, struct qmp_phy *qphy,
++                              struct device_node *np)
++{
++      struct clk_init_data init = { };
++      struct qmp_phy_dp_clks *dp_clks;
++      char name[64];
++      int ret;
++
++      dp_clks = devm_kzalloc(qmp->dev, sizeof(*dp_clks), GFP_KERNEL);
++      if (!dp_clks)
++              return -ENOMEM;
++
++      dp_clks->qphy = qphy;
++      qphy->dp_clks = dp_clks;
++
++      snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
++      init.ops = &qcom_qmp_dp_link_clk_ops;
++      init.name = name;
++      dp_clks->dp_link_hw.init = &init;
++      ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_link_hw);
++      if (ret)
++              return ret;
++
++      snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
++      init.ops = &qcom_qmp_dp_pixel_clk_ops;
++      init.name = name;
++      dp_clks->dp_pixel_hw.init = &init;
++      ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_pixel_hw);
++      if (ret)
++              return ret;
++
++      ret = of_clk_add_hw_provider(np, qcom_qmp_dp_clks_hw_get, dp_clks);
++      if (ret)
++              return ret;
++
++      /*
++       * Roll a devm action because the clock provider is the child node, but
++       * the child node is not actually a device.
++       */
++      return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
++}
++
++static const struct phy_ops qcom_qmp_phy_gen_ops = {
++      .init           = qcom_qmp_phy_enable,
++      .exit           = qcom_qmp_phy_disable,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static const struct phy_ops qcom_qmp_phy_dp_ops = {
++      .init           = qcom_qmp_phy_init,
++      .configure      = qcom_qmp_dp_phy_configure,
++      .power_on       = qcom_qmp_phy_power_on,
++      .calibrate      = qcom_qmp_dp_phy_calibrate,
++      .power_off      = qcom_qmp_phy_power_off,
++      .exit           = qcom_qmp_phy_exit,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static const struct phy_ops qcom_qmp_pcie_ufs_ops = {
++      .power_on       = qcom_qmp_phy_enable,
++      .power_off      = qcom_qmp_phy_disable,
++      .set_mode       = qcom_qmp_phy_set_mode,
++      .owner          = THIS_MODULE,
++};
++
++static void qcom_qmp_reset_control_put(void *data)
++{
++      reset_control_put(data);
++}
++
++static
++int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id,
++                      void __iomem *serdes, const struct qmp_phy_cfg *cfg)
++{
++      struct qcom_qmp *qmp = dev_get_drvdata(dev);
++      struct phy *generic_phy;
++      struct qmp_phy *qphy;
++      const struct phy_ops *ops;
++      char prop_name[MAX_PROP_NAME];
++      int ret;
++
++      qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
++      if (!qphy)
++              return -ENOMEM;
++
++      qphy->cfg = cfg;
++      qphy->serdes = serdes;
++      /*
++       * Get memory resources for each phy lane:
++       * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
++       * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
++       * For single lane PHYs: pcs_misc (optional) -> 3.
++       */
++      qphy->tx = of_iomap(np, 0);
++      if (!qphy->tx)
++              return -ENOMEM;
++
++      qphy->rx = of_iomap(np, 1);
++      if (!qphy->rx)
++              return -ENOMEM;
++
++      qphy->pcs = of_iomap(np, 2);
++      if (!qphy->pcs)
++              return -ENOMEM;
++
++      /*
++       * If this is a dual-lane PHY, then there should be registers for the
++       * second lane. Some old device trees did not specify this, so fall
++       * back to old legacy behavior of assuming they can be reached at an
++       * offset from the first lane.
++       */
++      if (cfg->is_dual_lane_phy) {
++              qphy->tx2 = of_iomap(np, 3);
++              qphy->rx2 = of_iomap(np, 4);
++              if (!qphy->tx2 || !qphy->rx2) {
++                      dev_warn(dev,
++                               "Underspecified device tree, falling back to legacy register regions\n");
++
++                      /* In the old version, pcs_misc is at index 3. */
++                      qphy->pcs_misc = qphy->tx2;
++                      qphy->tx2 = qphy->tx + QMP_PHY_LEGACY_LANE_STRIDE;
++                      qphy->rx2 = qphy->rx + QMP_PHY_LEGACY_LANE_STRIDE;
++
++              } else {
++                      qphy->pcs_misc = of_iomap(np, 5);
++              }
++
++      } else {
++              qphy->pcs_misc = of_iomap(np, 3);
++      }
++
++      if (!qphy->pcs_misc)
++              dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
++
++      /*
++       * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3
++       * based phys, so they essentially have pipe clock. So,
++       * we return error in case phy is USB3 or PIPE type.
++       * Otherwise, we initialize pipe clock to NULL for
++       * all phys that don't need this.
++       */
++      snprintf(prop_name, sizeof(prop_name), "pipe%d", id);
++      qphy->pipe_clk = devm_get_clk_from_child(dev, np, prop_name);
++      if (IS_ERR(qphy->pipe_clk)) {
++              if (cfg->type == PHY_TYPE_PCIE ||
++                  cfg->type == PHY_TYPE_USB3) {
++                      ret = PTR_ERR(qphy->pipe_clk);
++                      if (ret != -EPROBE_DEFER)
++                              dev_err(dev,
++                                      "failed to get lane%d pipe_clk, %d\n",
++                                      id, ret);
++                      return ret;
++              }
++              qphy->pipe_clk = NULL;
++      }
++
++      /* Get lane reset, if any */
++      if (cfg->has_lane_rst) {
++              snprintf(prop_name, sizeof(prop_name), "lane%d", id);
++              qphy->lane_rst = of_reset_control_get_exclusive(np, prop_name);
++              if (IS_ERR(qphy->lane_rst)) {
++                      dev_err(dev, "failed to get lane%d reset\n", id);
++                      return PTR_ERR(qphy->lane_rst);
++              }
++              ret = devm_add_action_or_reset(dev, qcom_qmp_reset_control_put,
++                                             qphy->lane_rst);
++              if (ret)
++                      return ret;
++      }
++
++      if (cfg->type == PHY_TYPE_UFS || cfg->type == PHY_TYPE_PCIE)
++              ops = &qcom_qmp_pcie_ufs_ops;
++      else if (cfg->type == PHY_TYPE_DP)
++              ops = &qcom_qmp_phy_dp_ops;
++      else
++              ops = &qcom_qmp_phy_gen_ops;
++
++      generic_phy = devm_phy_create(dev, np, ops);
++      if (IS_ERR(generic_phy)) {
++              ret = PTR_ERR(generic_phy);
++              dev_err(dev, "failed to create qphy %d\n", ret);
++              return ret;
++      }
++
++      qphy->phy = generic_phy;
++      qphy->index = id;
++      qphy->qmp = qmp;
++      qmp->phys[id] = qphy;
++      phy_set_drvdata(generic_phy, qphy);
++
++      return 0;
++}
++
++static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
++      {
++              .compatible = "qcom,ipq8074-qmp-usb3-phy",
++              .data = &ipq8074_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-pcie-phy",
++              .data = &msm8996_pciephy_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-ufs-phy",
++              .data = &msm8996_ufs_cfg,
++      }, {
++              .compatible = "qcom,msm8996-qmp-usb3-phy",
++              .data = &msm8996_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-pcie-phy",
++              .data = &msm8998_pciephy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,ipq8074-qmp-pcie-phy",
++              .data = &ipq8074_pciephy_cfg,
++      }, {
++              .compatible = "qcom,ipq6018-qmp-pcie-phy",
++              .data = &ipq6018_pciephy_cfg,
++      }, {
++              .compatible = "qcom,ipq6018-qmp-usb3-phy",
++              .data = &ipq8074_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc7180-qmp-usb3-phy",
++              .data = &sc7180_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sc8180x-qmp-pcie-phy",
++              .data = &sc8180x_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sc8280xp-qmp-ufs-phy",
++              .data = &sm8350_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-usb3-phy",
++              .data = &sm8150_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sdm845-qhp-pcie-phy",
++              .data = &sdm845_qhp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-pcie-phy",
++              .data = &sdm845_qmp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-usb3-phy",
++              .data = &qmp_v3_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-usb3-uni-phy",
++              .data = &qmp_v3_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sdm845-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,msm8998-qmp-usb3-phy",
++              .data = &msm8998_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm6115-qmp-ufs-phy",
++              .data = &sm6115_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm6350-qmp-ufs-phy",
++              .data = &sdm845_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-ufs-phy",
++              .data = &sm8150_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-usb3-phy",
++              .data = &sm8150_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8150-qmp-usb3-uni-phy",
++              .data = &sm8150_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-phy",
++              .data = &sm8250_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
++              /* It's a combo phy */
++      }, {
++              .compatible = "qcom,sm8250-qmp-usb3-uni-phy",
++              .data = &sm8250_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy",
++              .data = &sm8250_qmp_gen3x1_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-gen3x2-pcie-phy",
++              .data = &sm8250_qmp_gen3x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-ufs-phy",
++              .data = &sm8350_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8250-qmp-modem-pcie-phy",
++              .data = &sm8250_qmp_gen3x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdx55-qmp-pcie-phy",
++              .data = &sdx55_qmp_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sdx55-qmp-usb3-uni-phy",
++              .data = &sdx55_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sdx65-qmp-usb3-uni-phy",
++              .data = &sdx65_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-usb3-phy",
++              .data = &sm8350_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,sm8350-qmp-usb3-uni-phy",
++              .data = &sm8350_usb3_uniphy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-gen3x1-pcie-phy",
++              .data = &sm8450_qmp_gen3x1_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-gen4x2-pcie-phy",
++              .data = &sm8450_qmp_gen4x2_pciephy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-ufs-phy",
++              .data = &sm8450_ufsphy_cfg,
++      }, {
++              .compatible = "qcom,sm8450-qmp-usb3-phy",
++              .data = &sm8350_usb3phy_cfg,
++      }, {
++              .compatible = "qcom,qcm2290-qmp-usb3-phy",
++              .data = &qcm2290_usb3phy_cfg,
++      },
++      { },
++};
++MODULE_DEVICE_TABLE(of, qcom_qmp_phy_of_match_table);
++
++static const struct of_device_id qcom_qmp_combo_phy_of_match_table[] = {
++      {
++              .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
++              .data = &sc7180_usb3dpphy_cfg,
++      },
++      {
++              .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
++              .data = &sm8250_usb3dpphy_cfg,
++      },
++      {
++              .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
++              .data = &sc8180x_usb3dpphy_cfg,
++      },
++      { }
++};
++
++static const struct dev_pm_ops qcom_qmp_phy_pm_ops = {
++      SET_RUNTIME_PM_OPS(qcom_qmp_phy_runtime_suspend,
++                         qcom_qmp_phy_runtime_resume, NULL)
++};
++
++static int qcom_qmp_phy_probe(struct platform_device *pdev)
++{
++      struct qcom_qmp *qmp;
++      struct device *dev = &pdev->dev;
++      struct device_node *child;
++      struct phy_provider *phy_provider;
++      void __iomem *serdes;
++      void __iomem *usb_serdes;
++      void __iomem *dp_serdes = NULL;
++      const struct qmp_phy_combo_cfg *combo_cfg = NULL;
++      const struct qmp_phy_cfg *cfg = NULL;
++      const struct qmp_phy_cfg *usb_cfg = NULL;
++      const struct qmp_phy_cfg *dp_cfg = NULL;
++      int num, id, expected_phys;
++      int ret;
++
++      qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
++      if (!qmp)
++              return -ENOMEM;
++
++      qmp->dev = dev;
++      dev_set_drvdata(dev, qmp);
++
++      /* Get the specific init parameters of QMP phy */
++      cfg = of_device_get_match_data(dev);
++      if (!cfg) {
++              const struct of_device_id *match;
++
++              match = of_match_device(qcom_qmp_combo_phy_of_match_table, dev);
++              if (!match)
++                      return -EINVAL;
++
++              combo_cfg = match->data;
++              if (!combo_cfg)
++                      return -EINVAL;
++
++              usb_cfg = combo_cfg->usb_cfg;
++              cfg = usb_cfg; /* Setup clks and regulators */
++      }
++
++      /* per PHY serdes; usually located at base address */
++      usb_serdes = serdes = devm_platform_ioremap_resource(pdev, 0);
++      if (IS_ERR(serdes))
++              return PTR_ERR(serdes);
++
++      /* per PHY dp_com; if PHY has dp_com control block */
++      if (combo_cfg || cfg->has_phy_dp_com_ctrl) {
++              qmp->dp_com = devm_platform_ioremap_resource(pdev, 1);
++              if (IS_ERR(qmp->dp_com))
++                      return PTR_ERR(qmp->dp_com);
++      }
++
++      if (combo_cfg) {
++              /* Only two serdes for combo PHY */
++              dp_serdes = devm_platform_ioremap_resource(pdev, 2);
++              if (IS_ERR(dp_serdes))
++                      return PTR_ERR(dp_serdes);
++
++              dp_cfg = combo_cfg->dp_cfg;
++              expected_phys = 2;
++      } else {
++              expected_phys = cfg->nlanes;
++      }
++
++      mutex_init(&qmp->phy_mutex);
++
++      ret = qcom_qmp_phy_clk_init(dev, cfg);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_reset_init(dev, cfg);
++      if (ret)
++              return ret;
++
++      ret = qcom_qmp_phy_vreg_init(dev, cfg);
++      if (ret) {
++              if (ret != -EPROBE_DEFER)
++                      dev_err(dev, "failed to get regulator supplies: %d\n",
++                              ret);
++              return ret;
++      }
++
++      num = of_get_available_child_count(dev->of_node);
++      /* do we have a rogue child node ? */
++      if (num > expected_phys)
++              return -EINVAL;
++
++      qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
++      if (!qmp->phys)
++              return -ENOMEM;
++
++      pm_runtime_set_active(dev);
++      pm_runtime_enable(dev);
++      /*
++       * Prevent runtime pm from being ON by default. Users can enable
++       * it using power/control in sysfs.
++       */
++      pm_runtime_forbid(dev);
++
++      id = 0;
++      for_each_available_child_of_node(dev->of_node, child) {
++              if (of_node_name_eq(child, "dp-phy")) {
++                      cfg = dp_cfg;
++                      serdes = dp_serdes;
++              } else if (of_node_name_eq(child, "usb3-phy")) {
++                      cfg = usb_cfg;
++                      serdes = usb_serdes;
++              }
++
++              /* Create per-lane phy */
++              ret = qcom_qmp_phy_create(dev, child, id, serdes, cfg);
++              if (ret) {
++                      dev_err(dev, "failed to create lane%d phy, %d\n",
++                              id, ret);
++                      goto err_node_put;
++              }
++
++              /*
++               * Register the pipe clock provided by phy.
++               * See function description to see details of this pipe clock.
++               */
++              if (cfg->type == PHY_TYPE_USB3 || cfg->type == PHY_TYPE_PCIE) {
++                      ret = phy_pipe_clk_register(qmp, child);
++                      if (ret) {
++                              dev_err(qmp->dev,
++                                      "failed to register pipe clock source\n");
++                              goto err_node_put;
++                      }
++              } else if (cfg->type == PHY_TYPE_DP) {
++                      ret = phy_dp_clks_register(qmp, qmp->phys[id], child);
++                      if (ret) {
++                              dev_err(qmp->dev,
++                                      "failed to register DP clock source\n");
++                              goto err_node_put;
++                      }
++              }
++              id++;
++      }
++
++      phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
++      if (!IS_ERR(phy_provider))
++              dev_info(dev, "Registered Qcom-QMP phy\n");
++      else
++              pm_runtime_disable(dev);
++
++      return PTR_ERR_OR_ZERO(phy_provider);
++
++err_node_put:
++      pm_runtime_disable(dev);
++      of_node_put(child);
++      return ret;
++}
++
++static struct platform_driver qcom_qmp_phy_driver = {
++      .probe          = qcom_qmp_phy_probe,
++      .driver = {
++              .name   = "qcom-qmp-phy",
++              .pm     = &qcom_qmp_phy_pm_ops,
++              .of_match_table = qcom_qmp_phy_of_match_table,
++      },
++};
++
++module_platform_driver(qcom_qmp_phy_driver);
++
++MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
++MODULE_DESCRIPTION("Qualcomm QMP PHY driver");
++MODULE_LICENSE("GPL v2");
+-- 
+2.35.1
+
diff --git a/queue-5.10/phy-usb-s2-wol-wakeup_count-not-incremented-for-usb-.patch b/queue-5.10/phy-usb-s2-wol-wakeup_count-not-incremented-for-usb-.patch
new file mode 100644 (file)
index 0000000..0fecb17
--- /dev/null
@@ -0,0 +1,54 @@
+From ad96e123ff90d5b467b5026722c93256a409e683 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Oct 2022 14:30:14 -0700
+Subject: phy: usb: s2 WoL wakeup_count not incremented for USB->Eth devices
+
+From: Al Cooper <alcooperx@gmail.com>
+
+[ Upstream commit f7fc5b7090372fc4dd7798c874635ca41b8ba733 ]
+
+The PHY's "wakeup_count" is not incrementing when waking from
+WoL. The wakeup count can be found in sysfs at:
+/sys/bus/platform/devices/rdb/*.usb-phy/power/wakeup_count.
+The problem is that the system wakup event handler was being passed
+the wrong "device" by the PHY driver.
+
+Fixes: f1c0db40a3ad ("phy: usb: Add "wake on" functionality")
+Signed-off-by: Al Cooper <alcooperx@gmail.com>
+Signed-off-by: Justin Chen <justinpopo6@gmail.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Link: https://lore.kernel.org/r/1665005418-15807-3-git-send-email-justinpopo6@gmail.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/broadcom/phy-brcm-usb.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c
+index b901a0d4e2a8..cd2240ea2c9a 100644
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -101,9 +101,9 @@ static int brcm_pm_notifier(struct notifier_block *notifier,
+ static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id)
+ {
+-      struct phy *gphy = dev_id;
++      struct device *dev = dev_id;
+-      pm_wakeup_event(&gphy->dev, 0);
++      pm_wakeup_event(dev, 0);
+       return IRQ_HANDLED;
+ }
+@@ -437,7 +437,7 @@ static int brcm_usb_phy_dvr_init(struct platform_device *pdev,
+       if (priv->wake_irq >= 0) {
+               err = devm_request_irq(dev, priv->wake_irq,
+                                      brcm_usb_phy_wake_isr, 0,
+-                                     dev_name(dev), gphy);
++                                     dev_name(dev), dev);
+               if (err < 0)
+                       return err;
+               device_set_wakeup_capable(dev, 1);
+-- 
+2.35.1
+
diff --git a/queue-5.10/pinctrl-pinconf-generic-add-missing-of_node_put.patch b/queue-5.10/pinctrl-pinconf-generic-add-missing-of_node_put.patch
new file mode 100644 (file)
index 0000000..7cf758d
--- /dev/null
@@ -0,0 +1,40 @@
+From 3099aaa8507710b17efeac7e941782f468e5fe56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Nov 2022 07:01:56 +0000
+Subject: pinctrl: pinconf-generic: add missing of_node_put()
+
+From: ZhangPeng <zhangpeng362@huawei.com>
+
+[ Upstream commit 5ead93289815a075d43c415e35c8beafafb801c9 ]
+
+of_node_put() needs to be called when jumping out of the loop, since
+for_each_available_child_of_node() will increase the refcount of node.
+
+Fixes: c7289500e29d ("pinctrl: pinconf-generic: scan also referenced phandle node")
+Signed-off-by: ZhangPeng <zhangpeng362@huawei.com>
+Link: https://lore.kernel.org/r/20221125070156.3535855-1-zhangpeng362@huawei.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinconf-generic.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
+index 42e27dba62e2..762abb0dfebb 100644
+--- a/drivers/pinctrl/pinconf-generic.c
++++ b/drivers/pinctrl/pinconf-generic.c
+@@ -393,8 +393,10 @@ int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
+       for_each_available_child_of_node(np_config, np) {
+               ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map,
+                                       &reserved_maps, num_maps, type);
+-              if (ret < 0)
++              if (ret < 0) {
++                      of_node_put(np);
+                       goto exit;
++              }
+       }
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/platform-chrome-cros_usbpd_notify-fix-error-handling.patch b/queue-5.10/platform-chrome-cros_usbpd_notify-fix-error-handling.patch
new file mode 100644 (file)
index 0000000..517740b
--- /dev/null
@@ -0,0 +1,67 @@
+From 806ad52d2557669ceaa4ea937a93c6c86b551ec0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 08:08:23 +0000
+Subject: platform/chrome: cros_usbpd_notify: Fix error handling in
+ cros_usbpd_notify_init()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 5a2d96623670155d94aca72c320c0ac27bdc6bd2 ]
+
+The following WARNING message was given when rmmod cros_usbpd_notify:
+
+ Unexpected driver unregister!
+ WARNING: CPU: 0 PID: 253 at drivers/base/driver.c:270 driver_unregister+0x8a/0xb0
+ Modules linked in: cros_usbpd_notify(-)
+ CPU: 0 PID: 253 Comm: rmmod Not tainted 6.1.0-rc3 #24
+ ...
+ Call Trace:
+  <TASK>
+  cros_usbpd_notify_exit+0x11/0x1e [cros_usbpd_notify]
+  __x64_sys_delete_module+0x3c7/0x570
+  ? __ia32_sys_delete_module+0x570/0x570
+  ? lock_is_held_type+0xe3/0x140
+  ? syscall_enter_from_user_mode+0x17/0x50
+  ? rcu_read_lock_sched_held+0xa0/0xd0
+  ? syscall_enter_from_user_mode+0x1c/0x50
+  do_syscall_64+0x37/0x90
+  entry_SYSCALL_64_after_hwframe+0x63/0xcd
+ RIP: 0033:0x7f333fe9b1b7
+
+The reason is that the cros_usbpd_notify_init() does not check the return
+value of platform_driver_register(), and the cros_usbpd_notify can
+install successfully even if platform_driver_register() failed.
+
+Fix by checking the return value of platform_driver_register() and
+unregister cros_usbpd_notify_plat_driver when it failed.
+
+Fixes: ec2daf6e33f9 ("platform: chrome: Add cros-usbpd-notify driver")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Reviewed-by: Brian Norris <briannorris@chromium.org>
+Link: https://lore.kernel.org/r/20221117080823.77549-1-yuancan@huawei.com
+Signed-off-by: Prashant Malani <pmalani@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/chrome/cros_usbpd_notify.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/platform/chrome/cros_usbpd_notify.c b/drivers/platform/chrome/cros_usbpd_notify.c
+index 7f36142ab12a..19390147ac9d 100644
+--- a/drivers/platform/chrome/cros_usbpd_notify.c
++++ b/drivers/platform/chrome/cros_usbpd_notify.c
+@@ -284,7 +284,11 @@ static int __init cros_usbpd_notify_init(void)
+               return ret;
+ #ifdef CONFIG_ACPI
+-      platform_driver_register(&cros_usbpd_notify_acpi_driver);
++      ret = platform_driver_register(&cros_usbpd_notify_acpi_driver);
++      if (ret) {
++              platform_driver_unregister(&cros_usbpd_notify_plat_driver);
++              return ret;
++      }
+ #endif
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/platform-x86-huawei-wmi-fix-return-value-calculation.patch b/queue-5.10/platform-x86-huawei-wmi-fix-return-value-calculation.patch
new file mode 100644 (file)
index 0000000..9174636
--- /dev/null
@@ -0,0 +1,74 @@
+From 2630a4c7752ad88ca86524ea00dfb141d010ad87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Oct 2022 15:00:45 +0000
+Subject: platform/x86: huawei-wmi: fix return value calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Barnabás Pőcze <pobrn@protonmail.com>
+
+[ Upstream commit 0b9a1dcdb6a2c841899389bf2dd7a3e0e2aa0e99 ]
+
+Previously, `huawei_wmi_input_setup()` returned the result of
+logical or-ing the return values of two functions that return negative
+errno-style error codes and one that returns `acpi_status`. If this
+returned value was non-zero, then it was propagated from the platform
+driver's probe function. That function should return a negative
+errno-style error code, so the result of the logical or that
+`huawei_wmi_input_setup()` returned was not appropriate.
+
+Fix that by checking each function separately and returning the
+error code unmodified.
+
+Fixes: 1ac9abeb2e5b ("platform/x86: huawei-wmi: Move to platform driver")
+Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
+Link: https://lore.kernel.org/r/20221005150032.173198-2-pobrn@protonmail.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/huawei-wmi.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c
+index eac3e6b4ea11..935562c870c3 100644
+--- a/drivers/platform/x86/huawei-wmi.c
++++ b/drivers/platform/x86/huawei-wmi.c
+@@ -760,6 +760,9 @@ static int huawei_wmi_input_setup(struct device *dev,
+               const char *guid,
+               struct input_dev **idev)
+ {
++      acpi_status status;
++      int err;
++
+       *idev = devm_input_allocate_device(dev);
+       if (!*idev)
+               return -ENOMEM;
+@@ -769,10 +772,19 @@ static int huawei_wmi_input_setup(struct device *dev,
+       (*idev)->id.bustype = BUS_HOST;
+       (*idev)->dev.parent = dev;
+-      return sparse_keymap_setup(*idev, huawei_wmi_keymap, NULL) ||
+-              input_register_device(*idev) ||
+-              wmi_install_notify_handler(guid, huawei_wmi_input_notify,
+-                              *idev);
++      err = sparse_keymap_setup(*idev, huawei_wmi_keymap, NULL);
++      if (err)
++              return err;
++
++      err = input_register_device(*idev);
++      if (err)
++              return err;
++
++      status = wmi_install_notify_handler(guid, huawei_wmi_input_notify, *idev);
++      if (ACPI_FAILURE(status))
++              return -EIO;
++
++      return 0;
+ }
+ static void huawei_wmi_input_exit(struct device *dev, const char *guid)
+-- 
+2.35.1
+
diff --git a/queue-5.10/platform-x86-intel_scu_ipc-fix-possible-name-leak-in.patch b/queue-5.10/platform-x86-intel_scu_ipc-fix-possible-name-leak-in.patch
new file mode 100644 (file)
index 0000000..587fccd
--- /dev/null
@@ -0,0 +1,48 @@
+From f2665713af467d5098f5b293754628ea73805d9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 23:19:16 +0800
+Subject: platform/x86: intel_scu_ipc: fix possible name leak in
+ __intel_scu_ipc_register()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 0b3d0cb7c0bed2fd6454f77ed75e7a662c6efd12 ]
+
+In some error paths before device_register(), the names allocated
+by dev_set_name() are not freed. Move dev_set_name() front to
+device_register(), so the name can be freed while calling
+put_device().
+
+Fixes: 54b34aa0a729 ("platform/x86: intel_scu_ipc: Split out SCU IPC functionality from the SCU driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221208151916.2404977-1-yangyingliang@huawei.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel_scu_ipc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
+index 69d706039cb2..bdeb888c0fea 100644
+--- a/drivers/platform/x86/intel_scu_ipc.c
++++ b/drivers/platform/x86/intel_scu_ipc.c
+@@ -583,7 +583,6 @@ __intel_scu_ipc_register(struct device *parent,
+       scu->dev.parent = parent;
+       scu->dev.class = &intel_scu_ipc_class;
+       scu->dev.release = intel_scu_ipc_release;
+-      dev_set_name(&scu->dev, "intel_scu_ipc");
+       if (!request_mem_region(scu_data->mem.start, resource_size(&scu_data->mem),
+                               "intel_scu_ipc")) {
+@@ -612,6 +611,7 @@ __intel_scu_ipc_register(struct device *parent,
+        * After this point intel_scu_ipc_release() takes care of
+        * releasing the SCU IPC resources once refcount drops to zero.
+        */
++      dev_set_name(&scu->dev, "intel_scu_ipc");
+       err = device_register(&scu->dev);
+       if (err) {
+               put_device(&scu->dev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/platform-x86-mxm-wmi-fix-memleak-in-mxm_wmi_call_mx-.patch b/queue-5.10/platform-x86-mxm-wmi-fix-memleak-in-mxm_wmi_call_mx-.patch
new file mode 100644 (file)
index 0000000..c4f4ae6
--- /dev/null
@@ -0,0 +1,62 @@
+From 7c0d9ce0eb7372849b61d6b0c2c23008171f266c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 09:11:01 +0800
+Subject: platform/x86: mxm-wmi: fix memleak in mxm_wmi_call_mx[ds|mx]()
+
+From: Yu Liao <liaoyu15@huawei.com>
+
+[ Upstream commit 727cc0147f5066e359aca65cc6cc5e6d64cc15d8 ]
+
+The ACPI buffer memory (out.pointer) returned by wmi_evaluate_method()
+is not freed after the call, so it leads to memory leak.
+
+The method results in ACPI buffer is not used, so just pass NULL to
+wmi_evaluate_method() which fixes the memory leak.
+
+Fixes: 99b38b4acc0d ("platform/x86: add MXM WMI driver.")
+Signed-off-by: Yu Liao <liaoyu15@huawei.com>
+Link: https://lore.kernel.org/r/20221129011101.2042315-1-liaoyu15@huawei.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/mxm-wmi.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/platform/x86/mxm-wmi.c b/drivers/platform/x86/mxm-wmi.c
+index 9a19fbd2f734..9a457956025a 100644
+--- a/drivers/platform/x86/mxm-wmi.c
++++ b/drivers/platform/x86/mxm-wmi.c
+@@ -35,13 +35,11 @@ int mxm_wmi_call_mxds(int adapter)
+               .xarg = 1,
+       };
+       struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+-      struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+       acpi_status status;
+       printk("calling mux switch %d\n", adapter);
+-      status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input,
+-                                   &output);
++      status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, NULL);
+       if (ACPI_FAILURE(status))
+               return status;
+@@ -60,13 +58,11 @@ int mxm_wmi_call_mxmx(int adapter)
+               .xarg = 1,
+       };
+       struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+-      struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+       acpi_status status;
+       printk("calling mux switch %d\n", adapter);
+-      status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input,
+-                                   &output);
++      status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, NULL);
+       if (ACPI_FAILURE(status))
+               return status;
+-- 
+2.35.1
+
diff --git a/queue-5.10/pm-hibernate-fix-mistake-in-kerneldoc-comment.patch b/queue-5.10/pm-hibernate-fix-mistake-in-kerneldoc-comment.patch
new file mode 100644 (file)
index 0000000..0161b40
--- /dev/null
@@ -0,0 +1,45 @@
+From 79f18e08d39bed21d3ca70862023ad196a6824bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 10:28:39 +0800
+Subject: PM: hibernate: Fix mistake in kerneldoc comment
+
+From: xiongxin <xiongxin@kylinos.cn>
+
+[ Upstream commit 6e5d7300cbe7c3541bc31f16db3e9266e6027b4b ]
+
+The actual maximum image size formula in hibernate_preallocate_memory()
+is as follows:
+
+max_size = (count - (size + PAGES_FOR_IO)) / 2
+           - 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE);
+
+but the one in the kerneldoc comment of the function is different and
+incorrect.
+
+Fixes: ddeb64870810 ("PM / Hibernate: Add sysfs knob to control size of memory for drivers")
+Signed-off-by: xiongxin <xiongxin@kylinos.cn>
+[ rjw: Subject and changelog rewrite ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/power/snapshot.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
+index 1da013f50059..f5dccd445d36 100644
+--- a/kernel/power/snapshot.c
++++ b/kernel/power/snapshot.c
+@@ -1677,8 +1677,8 @@ static unsigned long minimum_image_size(unsigned long saveable)
+  * /sys/power/reserved_size, respectively).  To make this happen, we compute the
+  * total number of available page frames and allocate at least
+  *
+- * ([page frames total] + PAGES_FOR_IO + [metadata pages]) / 2
+- *  + 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE)
++ * ([page frames total] - PAGES_FOR_IO - [metadata pages]) / 2
++ *  - 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE)
+  *
+  * of them, which corresponds to the maximum size of a hibernation image.
+  *
+-- 
+2.35.1
+
diff --git a/queue-5.10/pm-runtime-do-not-call-__rpm_callback-from-rpm_idle.patch b/queue-5.10/pm-runtime-do-not-call-__rpm_callback-from-rpm_idle.patch
new file mode 100644 (file)
index 0000000..66bb723
--- /dev/null
@@ -0,0 +1,54 @@
+From 11141cbef1acbbe1ebead34d8b1ebf1b17cfeecb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 15:30:28 +0100
+Subject: PM: runtime: Do not call __rpm_callback() from rpm_idle()
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit bc80c2e438dcbfcf748452ec0f7ad5b79ff3ad88 ]
+
+Calling __rpm_callback() from rpm_idle() after adding device links
+support to the former is a clear mistake.
+
+Not only it causes rpm_idle() to carry out unnecessary actions, but it
+is also against the assumption regarding the stability of PM-runtime
+status across __rpm_callback() invocations, because rpm_suspend() and
+rpm_resume() may run in parallel with __rpm_callback() when it is called
+by rpm_idle() and the device's PM-runtime status can be updated by any
+of them.
+
+Fixes: 21d5c57b3726 ("PM / runtime: Use device links")
+Link: https://lore.kernel.org/linux-pm/36aed941-a73e-d937-2721-4f0decd61ce0@quicinc.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/runtime.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+index 532d910fe1cf..360094692d29 100644
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -483,7 +483,17 @@ static int rpm_idle(struct device *dev, int rpmflags)
+       dev->power.idle_notification = true;
+-      retval = __rpm_callback(callback, dev);
++      if (dev->power.irq_safe)
++              spin_unlock(&dev->power.lock);
++      else
++              spin_unlock_irq(&dev->power.lock);
++
++      retval = callback(dev);
++
++      if (dev->power.irq_safe)
++              spin_lock(&dev->power.lock);
++      else
++              spin_lock_irq(&dev->power.lock);
+       dev->power.idle_notification = false;
+       wake_up_all(&dev->power.wait_queue);
+-- 
+2.35.1
+
diff --git a/queue-5.10/pm-runtime-improve-path-in-rpm_idle-when-no-callback.patch b/queue-5.10/pm-runtime-improve-path-in-rpm_idle-when-no-callback.patch
new file mode 100644 (file)
index 0000000..69226c3
--- /dev/null
@@ -0,0 +1,59 @@
+From 31aadb3ea8177dd57714d84ab46c7d5c045df38e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Jun 2021 11:02:48 +0200
+Subject: PM: runtime: Improve path in rpm_idle() when no callback
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit 5a2bd1b1c64e1ac5627db3767ac465f18606315c ]
+
+When pm_runtime_no_callbacks() has been called for a struct device to set
+the dev->power.no_callbacks flag for it, it enables rpm_idle() to take a
+slightly quicker path by assuming that a ->runtime_idle() callback would
+have returned 0 to indicate success.
+
+A device that does not have the dev->power.no_callbacks flag set for it,
+may still be missing a corresponding ->runtime_idle() callback, in which
+case the slower path in rpm_idle() is taken. Let's improve the behaviour
+for this case, by aligning code to the quicker path.
+
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: bc80c2e438dc ("PM: runtime: Do not call __rpm_callback() from rpm_idle()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/runtime.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+index 835a39e84c1d..532d910fe1cf 100644
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -464,7 +464,10 @@ static int rpm_idle(struct device *dev, int rpmflags)
+       /* Pending requests need to be canceled. */
+       dev->power.request = RPM_REQ_NONE;
+-      if (dev->power.no_callbacks)
++      callback = RPM_GET_CALLBACK(dev, runtime_idle);
++
++      /* If no callback assume success. */
++      if (!callback || dev->power.no_callbacks)
+               goto out;
+       /* Carry out an asynchronous or a synchronous idle notification. */
+@@ -480,10 +483,7 @@ static int rpm_idle(struct device *dev, int rpmflags)
+       dev->power.idle_notification = true;
+-      callback = RPM_GET_CALLBACK(dev, runtime_idle);
+-
+-      if (callback)
+-              retval = __rpm_callback(callback, dev);
++      retval = __rpm_callback(callback, dev);
+       dev->power.idle_notification = false;
+       wake_up_all(&dev->power.wait_queue);
+-- 
+2.35.1
+
diff --git a/queue-5.10/pnp-fix-name-memory-leak-in-pnp_alloc_dev.patch b/queue-5.10/pnp-fix-name-memory-leak-in-pnp_alloc_dev.patch
new file mode 100644 (file)
index 0000000..66806fe
--- /dev/null
@@ -0,0 +1,46 @@
+From 9d998a74ac31b6858a0bc5c9ac0e6f44baa45baa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 09:23:58 +0800
+Subject: PNP: fix name memory leak in pnp_alloc_dev()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 110d7b0325c55ff3620073ba4201845f59e22ebf ]
+
+After commit 1fa5ae857bb1 ("driver core: get rid of struct device's
+bus_id string array"), the name of device is allocated dynamically,
+move dev_set_name() after pnp_add_id() to avoid memory leak.
+
+Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pnp/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
+index a50ab002e9e4..14bf75ba941d 100644
+--- a/drivers/pnp/core.c
++++ b/drivers/pnp/core.c
+@@ -160,14 +160,14 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id,
+       dev->dev.coherent_dma_mask = dev->dma_mask;
+       dev->dev.release = &pnp_release_device;
+-      dev_set_name(&dev->dev, "%02x:%02x", dev->protocol->number, dev->number);
+-
+       dev_id = pnp_add_id(dev, pnpid);
+       if (!dev_id) {
+               kfree(dev);
+               return NULL;
+       }
++      dev_set_name(&dev->dev, "%02x:%02x", dev->protocol->number, dev->number);
++
+       return dev;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/power-supply-fix-null-pointer-dereferencing-in-power.patch b/queue-5.10/power-supply-fix-null-pointer-dereferencing-in-power.patch
new file mode 100644 (file)
index 0000000..2cdf699
--- /dev/null
@@ -0,0 +1,44 @@
+From 898504251447f783b65e83a45bdeeeaa61c2c9f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 15:51:53 +0800
+Subject: power: supply: fix null pointer dereferencing in
+ power_supply_get_battery_info
+
+From: ruanjinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit 104bb8a663451404a26331263ce5b96c34504049 ]
+
+when kmalloc() fail to allocate memory in kasprintf(), propname
+will be NULL, strcmp() called by of_get_property() will cause
+null pointer dereference.
+
+So return ENOMEM if kasprintf() return NULL pointer.
+
+Fixes: 3afb50d7125b ("power: supply: core: Add some helpers to use the battery OCV capacity table")
+Signed-off-by: ruanjinjie <ruanjinjie@huawei.com>
+Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/power_supply_core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
+index be2cb925c115..2b644590fa8e 100644
+--- a/drivers/power/supply/power_supply_core.c
++++ b/drivers/power/supply/power_supply_core.c
+@@ -677,6 +677,11 @@ int power_supply_get_battery_info(struct power_supply *psy,
+               int i, tab_len, size;
+               propname = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", index);
++              if (!propname) {
++                      power_supply_put_battery_info(psy, info);
++                      err = -ENOMEM;
++                      goto out_put_node;
++              }
+               list = of_get_property(battery_np, propname, &size);
+               if (!list || !size) {
+                       dev_err(&psy->dev, "failed to get %s\n", propname);
+-- 
+2.35.1
+
diff --git a/queue-5.10/power-supply-fix-residue-sysfs-file-in-error-handle-.patch b/queue-5.10/power-supply-fix-residue-sysfs-file-in-error-handle-.patch
new file mode 100644 (file)
index 0000000..ff7eb7f
--- /dev/null
@@ -0,0 +1,50 @@
+From 35f86d3ccab7ebbe4ab5a65d3d0ffbb2fd46aca4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 16:32:19 +0800
+Subject: power: supply: fix residue sysfs file in error handle route of
+ __power_supply_register()
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit 5b79480ce1978864ac3f06f2134dfa3b6691fe74 ]
+
+If device_add() succeeds, we should call device_del() when want to
+get rid of it, so move it into proper jump symbol.
+
+Otherwise, when __power_supply_register() returns fail and goto
+wakeup_init_failed to exit, there is still residue device file in sysfs.
+When attempt to probe device again, sysfs would complain as below:
+
+sysfs: cannot create duplicate filename '/devices/platform/i2c/i2c-0/0-001c/power_supply/adp5061'
+Call Trace:
+ dump_stack_lvl+0x68/0x85
+ sysfs_warn_dup.cold+0x1c/0x29
+ sysfs_create_dir_ns+0x1b1/0x1d0
+ kobject_add_internal+0x143/0x390
+ kobject_add+0x108/0x170
+
+Fixes: 80c6463e2fa3 ("power_supply: Fix Oops from NULL pointer dereference from wakeup_source_activate")
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/power_supply_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
+index 280c54c23e37..be2cb925c115 100644
+--- a/drivers/power/supply/power_supply_core.c
++++ b/drivers/power/supply/power_supply_core.c
+@@ -1201,8 +1201,8 @@ __power_supply_register(struct device *parent,
+ register_cooler_failed:
+       psy_unregister_thermal(psy);
+ register_thermal_failed:
+-      device_del(dev);
+ wakeup_init_failed:
++      device_del(dev);
+ device_add_failed:
+ check_supplies_failed:
+ dev_set_name_failed:
+-- 
+2.35.1
+
diff --git a/queue-5.10/powerpc-52xx-fix-a-resource-leak-in-an-error-handlin.patch b/queue-5.10/powerpc-52xx-fix-a-resource-leak-in-an-error-handlin.patch
new file mode 100644 (file)
index 0000000..8e93d88
--- /dev/null
@@ -0,0 +1,38 @@
+From 5f55f3236408ee03e0a51769d89b437de788bbfb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Jan 2022 08:16:04 +0100
+Subject: powerpc/52xx: Fix a resource leak in an error handling path
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 5836947613ef33d311b4eff6a32d019580a214f5 ]
+
+The error handling path of mpc52xx_lpbfifo_probe() has a request_irq()
+that is not balanced by a corresponding free_irq().
+
+Add the missing call, as already done in the remove function.
+
+Fixes: 3c9059d79f5e ("powerpc/5200: add LocalPlus bus FIFO device driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/dec1496d46ccd5311d0f6e9f9ca4238be11bf6a6.1643440531.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+index 05e19470d523..22e264bd3ed2 100644
+--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
++++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+@@ -530,6 +530,7 @@ static int mpc52xx_lpbfifo_probe(struct platform_device *op)
+  err_bcom_rx_irq:
+       bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
+  err_bcom_rx:
++      free_irq(lpbfifo.irq, &lpbfifo);
+  err_irq:
+       iounmap(lpbfifo.regs);
+       lpbfifo.regs = NULL;
+-- 
+2.35.1
+
diff --git a/queue-5.10/powerpc-83xx-mpc832x_rdb-call-platform_device_put-in.patch b/queue-5.10/powerpc-83xx-mpc832x_rdb-call-platform_device_put-in.patch
new file mode 100644 (file)
index 0000000..a2346fc
--- /dev/null
@@ -0,0 +1,39 @@
+From 3aa0d5fc57a2c14b22921c48662c87fd3e4e16dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Oct 2022 19:16:26 +0800
+Subject: powerpc/83xx/mpc832x_rdb: call platform_device_put() in error case in
+ of_fsl_spi_probe()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 4d0eea415216fe3791da2f65eb41399e70c7bedf ]
+
+If platform_device_add() is not called or failed, it can not call
+platform_device_del() to clean up memory, it should call
+platform_device_put() in error case.
+
+Fixes: 26f6cb999366 ("[POWERPC] fsl_soc: add support for fsl_spi")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20221029111626.429971-1-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/83xx/mpc832x_rdb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+index 622c625d5ce4..1114b6a11b3f 100644
+--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
++++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+@@ -106,7 +106,7 @@ static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
+               goto next;
+ unreg:
+-              platform_device_del(pdev);
++              platform_device_put(pdev);
+ err:
+               pr_err("%pOF: registration failed\n", np);
+ next:
+-- 
+2.35.1
+
diff --git a/queue-5.10/powerpc-dts-t208x-mark-mac1-and-mac2-as-10g.patch b/queue-5.10/powerpc-dts-t208x-mark-mac1-and-mac2-as-10g.patch
new file mode 100644 (file)
index 0000000..15828bb
--- /dev/null
@@ -0,0 +1,142 @@
+From 8e60735bc53f2dbaa46787b087ecc07bd4833591 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Oct 2022 16:22:39 -0400
+Subject: powerpc: dts: t208x: Mark MAC1 and MAC2 as 10G
+
+From: Sean Anderson <sean.anderson@seco.com>
+
+[ Upstream commit 36926a7d70c2d462fca1ed85bfee000d17fd8662 ]
+
+On the T208X SoCs, MAC1 and MAC2 support XGMII. Add some new MAC dtsi
+fragments, and mark the QMAN ports as 10G.
+
+Fixes: da414bb923d9 ("powerpc/mpc85xx: Add FSL QorIQ DPAA FMan support to the SoC device tree(s)")
+Signed-off-by: Sean Anderson <sean.anderson@seco.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi     | 44 +++++++++++++++++++
+ .../boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi     | 44 +++++++++++++++++++
+ arch/powerpc/boot/dts/fsl/t2081si-post.dtsi   |  4 +-
+ 3 files changed, 90 insertions(+), 2 deletions(-)
+ create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi
+ create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi
+
+diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi
+new file mode 100644
+index 000000000000..437dab3fc017
+--- /dev/null
++++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi
+@@ -0,0 +1,44 @@
++// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later
++/*
++ * QorIQ FMan v3 10g port #2 device tree stub [ controller @ offset 0x400000 ]
++ *
++ * Copyright 2022 Sean Anderson <sean.anderson@seco.com>
++ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
++ */
++
++fman@400000 {
++      fman0_rx_0x08: port@88000 {
++              cell-index = <0x8>;
++              compatible = "fsl,fman-v3-port-rx";
++              reg = <0x88000 0x1000>;
++              fsl,fman-10g-port;
++      };
++
++      fman0_tx_0x28: port@a8000 {
++              cell-index = <0x28>;
++              compatible = "fsl,fman-v3-port-tx";
++              reg = <0xa8000 0x1000>;
++              fsl,fman-10g-port;
++      };
++
++      ethernet@e0000 {
++              cell-index = <0>;
++              compatible = "fsl,fman-memac";
++              reg = <0xe0000 0x1000>;
++              fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>;
++              ptp-timer = <&ptp_timer0>;
++              pcsphy-handle = <&pcsphy0>;
++      };
++
++      mdio@e1000 {
++              #address-cells = <1>;
++              #size-cells = <0>;
++              compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
++              reg = <0xe1000 0x1000>;
++              fsl,erratum-a011043; /* must ignore read errors */
++
++              pcsphy0: ethernet-phy@0 {
++                      reg = <0x0>;
++              };
++      };
++};
+diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi
+new file mode 100644
+index 000000000000..ad116b17850a
+--- /dev/null
++++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi
+@@ -0,0 +1,44 @@
++// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later
++/*
++ * QorIQ FMan v3 10g port #3 device tree stub [ controller @ offset 0x400000 ]
++ *
++ * Copyright 2022 Sean Anderson <sean.anderson@seco.com>
++ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
++ */
++
++fman@400000 {
++      fman0_rx_0x09: port@89000 {
++              cell-index = <0x9>;
++              compatible = "fsl,fman-v3-port-rx";
++              reg = <0x89000 0x1000>;
++              fsl,fman-10g-port;
++      };
++
++      fman0_tx_0x29: port@a9000 {
++              cell-index = <0x29>;
++              compatible = "fsl,fman-v3-port-tx";
++              reg = <0xa9000 0x1000>;
++              fsl,fman-10g-port;
++      };
++
++      ethernet@e2000 {
++              cell-index = <1>;
++              compatible = "fsl,fman-memac";
++              reg = <0xe2000 0x1000>;
++              fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>;
++              ptp-timer = <&ptp_timer0>;
++              pcsphy-handle = <&pcsphy1>;
++      };
++
++      mdio@e3000 {
++              #address-cells = <1>;
++              #size-cells = <0>;
++              compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
++              reg = <0xe3000 0x1000>;
++              fsl,erratum-a011043; /* must ignore read errors */
++
++              pcsphy1: ethernet-phy@0 {
++                      reg = <0x0>;
++              };
++      };
++};
+diff --git a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
+index ecbb447920bc..74e17e134387 100644
+--- a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
++++ b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
+@@ -609,8 +609,8 @@ usb1: usb@211000 {
+ /include/ "qoriq-bman1.dtsi"
+ /include/ "qoriq-fman3-0.dtsi"
+-/include/ "qoriq-fman3-0-1g-0.dtsi"
+-/include/ "qoriq-fman3-0-1g-1.dtsi"
++/include/ "qoriq-fman3-0-10g-2.dtsi"
++/include/ "qoriq-fman3-0-10g-3.dtsi"
+ /include/ "qoriq-fman3-0-1g-2.dtsi"
+ /include/ "qoriq-fman3-0-1g-3.dtsi"
+ /include/ "qoriq-fman3-0-1g-4.dtsi"
+-- 
+2.35.1
+
diff --git a/queue-5.10/powerpc-eeh-drop-redundant-spinlock-initialization.patch b/queue-5.10/powerpc-eeh-drop-redundant-spinlock-initialization.patch
new file mode 100644 (file)
index 0000000..e5f0957
--- /dev/null
@@ -0,0 +1,38 @@
+From 4fb838045cc565c0f7f52cbc16cd1f4a56664ddf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 09:27:56 +0800
+Subject: powerpc/eeh: Drop redundant spinlock initialization
+
+From: Haowen Bai <baihaowen@meizu.com>
+
+[ Upstream commit 3def164a5cedad9117859dd4610cae2cc59cb6d2 ]
+
+slot_errbuf_lock has declared and initialized by DEFINE_SPINLOCK,
+so we don't need to spin_lock_init again, drop it.
+
+Signed-off-by: Haowen Bai <baihaowen@meizu.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/1652232476-9696-1-git-send-email-baihaowen@meizu.com
+Stable-dep-of: 9aafbfa5f57a ("powerpc/pseries/eeh: use correct API for error log size")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/eeh_pseries.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
+index 7ed38ebd0c7b..6ad8bda06345 100644
+--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
+@@ -846,8 +846,7 @@ static int __init eeh_pseries_init(void)
+               return -EINVAL;
+       }
+-      /* Initialize error log lock and size */
+-      spin_lock_init(&slot_errbuf_lock);
++      /* Initialize error log size */
+       eeh_error_buf_size = rtas_token("rtas-error-log-max");
+       if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
+               pr_info("%s: unknown EEH error log size\n",
+-- 
+2.35.1
+
diff --git a/queue-5.10/powerpc-hv-gpci-fix-hv_gpci-event-list.patch b/queue-5.10/powerpc-hv-gpci-fix-hv_gpci-event-list.patch
new file mode 100644 (file)
index 0000000..04ebad0
--- /dev/null
@@ -0,0 +1,174 @@
+From 136324f5c3fb9a064fadaa16947b5e9514a1f3dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Nov 2022 23:15:13 +0530
+Subject: powerpc/hv-gpci: Fix hv_gpci event list
+
+From: Kajol Jain <kjain@linux.ibm.com>
+
+[ Upstream commit 03f7c1d2a49acd30e38789cd809d3300721e9b0e ]
+
+Based on getPerfCountInfo v1.018 documentation, some of the
+hv_gpci events were deprecated for platform firmware that
+supports counter_info_version 0x8 or above.
+
+Fix the hv_gpci event list by adding a new attribute group
+called "hv_gpci_event_attrs_v6" and a "ENABLE_EVENTS_COUNTERINFO_V6"
+macro to enable these events for platform firmware
+that supports counter_info_version 0x6 or below. And assigning
+the hv_gpci event list based on output counter info version
+of underlying plaform.
+
+Fixes: 97bf2640184f ("powerpc/perf/hv-gpci: add the remaining gpci requests")
+Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
+Reviewed-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Reviewed-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20221130174513.87501-1-kjain@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/hv-gpci-requests.h |  4 ++++
+ arch/powerpc/perf/hv-gpci.c          | 33 +++++++++++++++++++++++++++-
+ arch/powerpc/perf/hv-gpci.h          |  1 +
+ arch/powerpc/perf/req-gen/perf.h     | 20 +++++++++++++++++
+ 4 files changed, 57 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/perf/hv-gpci-requests.h b/arch/powerpc/perf/hv-gpci-requests.h
+index 8965b4463d43..5e86371a20c7 100644
+--- a/arch/powerpc/perf/hv-gpci-requests.h
++++ b/arch/powerpc/perf/hv-gpci-requests.h
+@@ -79,6 +79,7 @@ REQUEST(__field(0,   8,      partition_id)
+ )
+ #include I(REQUEST_END)
++#ifdef ENABLE_EVENTS_COUNTERINFO_V6
+ /*
+  * Not available for counter_info_version >= 0x8, use
+  * run_instruction_cycles_by_partition(0x100) instead.
+@@ -92,6 +93,7 @@ REQUEST(__field(0,   8,      partition_id)
+       __count(0x10,   8,      cycles)
+ )
+ #include I(REQUEST_END)
++#endif
+ #define REQUEST_NAME system_performance_capabilities
+ #define REQUEST_NUM 0x40
+@@ -103,6 +105,7 @@ REQUEST(__field(0, 1,      perf_collect_privileged)
+ )
+ #include I(REQUEST_END)
++#ifdef ENABLE_EVENTS_COUNTERINFO_V6
+ #define REQUEST_NAME processor_bus_utilization_abc_links
+ #define REQUEST_NUM 0x50
+ #define REQUEST_IDX_KIND "hw_chip_id=?"
+@@ -194,6 +197,7 @@ REQUEST(__field(0, 4,      phys_processor_idx)
+       __count(0x28,   8,      instructions_completed)
+ )
+ #include I(REQUEST_END)
++#endif
+ /* Processor_core_power_mode (0x95) skipped, no counters */
+ /* Affinity_domain_information_by_virtual_processor (0xA0) skipped,
+diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
+index c756228a081f..28b770bbc10b 100644
+--- a/arch/powerpc/perf/hv-gpci.c
++++ b/arch/powerpc/perf/hv-gpci.c
+@@ -72,7 +72,7 @@ static struct attribute_group format_group = {
+ static struct attribute_group event_group = {
+       .name  = "events",
+-      .attrs = hv_gpci_event_attrs,
++      /* .attrs is set in init */
+ };
+ #define HV_CAPS_ATTR(_name, _format)                          \
+@@ -330,6 +330,7 @@ static int hv_gpci_init(void)
+       int r;
+       unsigned long hret;
+       struct hv_perf_caps caps;
++      struct hv_gpci_request_buffer *arg;
+       hv_gpci_assert_offsets_correct();
+@@ -353,6 +354,36 @@ static int hv_gpci_init(void)
+       /* sampling not supported */
+       h_gpci_pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
++      arg = (void *)get_cpu_var(hv_gpci_reqb);
++      memset(arg, 0, HGPCI_REQ_BUFFER_SIZE);
++
++      /*
++       * hcall H_GET_PERF_COUNTER_INFO populates the output
++       * counter_info_version value based on the system hypervisor.
++       * Pass the counter request 0x10 corresponds to request type
++       * 'Dispatch_timebase_by_processor', to get the supported
++       * counter_info_version.
++       */
++      arg->params.counter_request = cpu_to_be32(0x10);
++
++      r = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
++                      virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE);
++      if (r) {
++              pr_devel("hcall failed, can't get supported counter_info_version: 0x%x\n", r);
++              arg->params.counter_info_version_out = 0x8;
++      }
++
++      /*
++       * Use counter_info_version_out value to assign
++       * required hv-gpci event list.
++       */
++      if (arg->params.counter_info_version_out >= 0x8)
++              event_group.attrs = hv_gpci_event_attrs;
++      else
++              event_group.attrs = hv_gpci_event_attrs_v6;
++
++      put_cpu_var(hv_gpci_reqb);
++
+       r = perf_pmu_register(&h_gpci_pmu, h_gpci_pmu.name, -1);
+       if (r)
+               return r;
+diff --git a/arch/powerpc/perf/hv-gpci.h b/arch/powerpc/perf/hv-gpci.h
+index 4d108262bed7..c72020912dea 100644
+--- a/arch/powerpc/perf/hv-gpci.h
++++ b/arch/powerpc/perf/hv-gpci.h
+@@ -26,6 +26,7 @@ enum {
+ #define REQUEST_FILE "../hv-gpci-requests.h"
+ #define NAME_LOWER hv_gpci
+ #define NAME_UPPER HV_GPCI
++#define ENABLE_EVENTS_COUNTERINFO_V6
+ #include "req-gen/perf.h"
+ #undef REQUEST_FILE
+ #undef NAME_LOWER
+diff --git a/arch/powerpc/perf/req-gen/perf.h b/arch/powerpc/perf/req-gen/perf.h
+index fa9bc804e67a..6b2a59fefffa 100644
+--- a/arch/powerpc/perf/req-gen/perf.h
++++ b/arch/powerpc/perf/req-gen/perf.h
+@@ -139,6 +139,26 @@ PMU_EVENT_ATTR_STRING(                                                    \
+ #define REQUEST_(r_name, r_value, r_idx_1, r_fields)                  \
+       r_fields
++/* Generate event list for platforms with counter_info_version 0x6 or below */
++static __maybe_unused struct attribute *hv_gpci_event_attrs_v6[] = {
++#include REQUEST_FILE
++      NULL
++};
++
++/*
++ * Based on getPerfCountInfo v1.018 documentation, some of the hv-gpci
++ * events were deprecated for platform firmware that supports
++ * counter_info_version 0x8 or above.
++ * Those deprecated events are still part of platform firmware that
++ * support counter_info_version 0x6 and below. As per the getPerfCountInfo
++ * v1.018 documentation there is no counter_info_version 0x7.
++ * Undefining macro ENABLE_EVENTS_COUNTERINFO_V6, to disable the addition of
++ * deprecated events in "hv_gpci_event_attrs" attribute group, for platforms
++ * that supports counter_info_version 0x8 or above.
++ */
++#undef ENABLE_EVENTS_COUNTERINFO_V6
++
++/* Generate event list for platforms with counter_info_version 0x8 or above*/
+ static __maybe_unused struct attribute *hv_gpci_event_attrs[] = {
+ #include REQUEST_FILE
+       NULL
+-- 
+2.35.1
+
diff --git a/queue-5.10/powerpc-perf-callchain-validate-kernel-stack-pointer.patch b/queue-5.10/powerpc-perf-callchain-validate-kernel-stack-pointer.patch
new file mode 100644 (file)
index 0000000..ce5af35
--- /dev/null
@@ -0,0 +1,46 @@
+From 98120f0cda56238fdb82c6b26d7184e55d93a0c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Nov 2022 22:49:28 +1000
+Subject: powerpc/perf: callchain validate kernel stack pointer bounds
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit 32c5209214bd8d4f8c4e9d9b630ef4c671f58e79 ]
+
+The interrupt frame detection and loads from the hypothetical pt_regs
+are not bounds-checked. The next-frame validation only bounds-checks
+STACK_FRAME_OVERHEAD, which does not include the pt_regs. Add another
+test for this.
+
+The user could set r1 to be equal to the address matching the first
+interrupt frame - STACK_INT_FRAME_SIZE, which is in the previous page
+due to the kernel redzone, and induce the kernel to load the marker from
+there. Possibly this could cause a crash at least. If the user could
+induce the previous page to contain a valid marker, then it might be
+able to direct perf to read specific memory addresses in a way that
+could be transmitted back to the user in the perf data.
+
+Fixes: 20002ded4d93 ("perf_counter: powerpc: Add callchain support")
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20221127124942.1665522-4-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/callchain.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
+index 6c028ee513c0..99f3c4fc21cb 100644
+--- a/arch/powerpc/perf/callchain.c
++++ b/arch/powerpc/perf/callchain.c
+@@ -61,6 +61,7 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
+               next_sp = fp[0];
+               if (next_sp == sp + STACK_INT_FRAME_SIZE &&
++                  validate_sp(sp, current, STACK_INT_FRAME_SIZE) &&
+                   fp[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
+                       /*
+                        * This looks like an interrupt frame for an
+-- 
+2.35.1
+
diff --git a/queue-5.10/powerpc-pseries-eeh-use-correct-api-for-error-log-si.patch b/queue-5.10/powerpc-pseries-eeh-use-correct-api-for-error-log-si.patch
new file mode 100644 (file)
index 0000000..69a7d04
--- /dev/null
@@ -0,0 +1,49 @@
+From 64c28a7b2ed9b0850ee21113b7195cbf1c9da806 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 09:07:43 -0600
+Subject: powerpc/pseries/eeh: use correct API for error log size
+
+From: Nathan Lynch <nathanl@linux.ibm.com>
+
+[ Upstream commit 9aafbfa5f57a4b75bafd3bed0191e8429c5fa618 ]
+
+rtas-error-log-max is not the name of an RTAS function, so rtas_token()
+is not the appropriate API for retrieving its value. We already have
+rtas_get_error_log_max() which returns a sensible value if the property
+is absent for any reason, so use that instead.
+
+Fixes: 8d633291b4fc ("powerpc/eeh: pseries platform EEH error log retrieval")
+Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
+[mpe: Drop no-longer possible error handling as noticed by ajd]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20221118150751.469393-6-nathanl@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/eeh_pseries.c | 11 +----------
+ 1 file changed, 1 insertion(+), 10 deletions(-)
+
+diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
+index 6ad8bda06345..4601ad10ca7b 100644
+--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
+@@ -847,16 +847,7 @@ static int __init eeh_pseries_init(void)
+       }
+       /* Initialize error log size */
+-      eeh_error_buf_size = rtas_token("rtas-error-log-max");
+-      if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
+-              pr_info("%s: unknown EEH error log size\n",
+-                      __func__);
+-              eeh_error_buf_size = 1024;
+-      } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
+-              pr_info("%s: EEH error log size %d exceeds the maximal %d\n",
+-                      __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
+-              eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
+-      }
++      eeh_error_buf_size = rtas_get_error_log_max();
+       /* Set EEH probe mode */
+       eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
+-- 
+2.35.1
+
diff --git a/queue-5.10/powerpc-xive-add-missing-iounmap-in-error-path-in-xi.patch b/queue-5.10/powerpc-xive-add-missing-iounmap-in-error-path-in-xi.patch
new file mode 100644 (file)
index 0000000..69ac1b9
--- /dev/null
@@ -0,0 +1,41 @@
+From 14ac96c88870ac3002eaac80c496239fc70fee8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Oct 2022 11:23:33 +0800
+Subject: powerpc/xive: add missing iounmap() in error path in
+ xive_spapr_populate_irq_data()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 8b49670f3bb3f10cd4d5a6dca17f5a31b173ecdc ]
+
+If remapping 'data->trig_page' fails, the 'data->eoi_mmio' need be unmapped
+before returning from xive_spapr_populate_irq_data().
+
+Fixes: eac1e731b59e ("powerpc/xive: guest exploitation of the XIVE interrupt controller")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Cédric Le Goater <clg@kaod.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20221017032333.1852406-1-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/sysdev/xive/spapr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
+index 38e8b9896174..53cf14349d5e 100644
+--- a/arch/powerpc/sysdev/xive/spapr.c
++++ b/arch/powerpc/sysdev/xive/spapr.c
+@@ -425,6 +425,7 @@ static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data)
+       data->trig_mmio = ioremap(data->trig_page, 1u << data->esb_shift);
+       if (!data->trig_mmio) {
++              iounmap(data->eoi_mmio);
+               pr_err("Failed to map trigger page for irq 0x%x\n", hw_irq);
+               return -ENOMEM;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/powerpc-xmon-enable-breakpoints-on-8xx.patch b/queue-5.10/powerpc-xmon-enable-breakpoints-on-8xx.patch
new file mode 100644 (file)
index 0000000..cf0acd2
--- /dev/null
@@ -0,0 +1,62 @@
+From c30c973efebc16e630ec3cc1f76557433103cf5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Dec 2020 09:38:48 +0000
+Subject: powerpc/xmon: Enable breakpoints on 8xx
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 30662217885d7341161924acf1665924d7d37d64 ]
+
+Since commit 4ad8622dc548 ("powerpc/8xx: Implement hw_breakpoint"),
+8xx has breakpoints so there is no reason to opt breakpoint logic
+out of xmon for the 8xx.
+
+Fixes: 4ad8622dc548 ("powerpc/8xx: Implement hw_breakpoint")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/b0607f1113d1558e73476bb06db0ee16d31a6e5b.1608716197.git.christophe.leroy@csgroup.eu
+Stable-dep-of: 1c4a4a4c8410 ("powerpc/xmon: Fix -Wswitch-unreachable warning in bpt_cmds")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/xmon/xmon.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
+index 5559edf36756..c6a36b4045e8 100644
+--- a/arch/powerpc/xmon/xmon.c
++++ b/arch/powerpc/xmon/xmon.c
+@@ -1383,7 +1383,6 @@ static long check_bp_loc(unsigned long addr)
+       return 1;
+ }
+-#ifndef CONFIG_PPC_8xx
+ static int find_free_data_bpt(void)
+ {
+       int i;
+@@ -1395,7 +1394,6 @@ static int find_free_data_bpt(void)
+       printf("Couldn't find free breakpoint register\n");
+       return -1;
+ }
+-#endif
+ static void print_data_bpts(void)
+ {
+@@ -1435,7 +1433,6 @@ bpt_cmds(void)
+       cmd = inchar();
+       switch (cmd) {
+-#ifndef CONFIG_PPC_8xx
+       static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
+       int mode;
+       case 'd':       /* bd - hardware data breakpoint */
+@@ -1497,7 +1494,6 @@ bpt_cmds(void)
+                       force_enable_xmon();
+               }
+               break;
+-#endif
+       case 'c':
+               if (!scanhex(&a)) {
+-- 
+2.35.1
+
diff --git a/queue-5.10/powerpc-xmon-fix-wswitch-unreachable-warning-in-bpt_.patch b/queue-5.10/powerpc-xmon-fix-wswitch-unreachable-warning-in-bpt_.patch
new file mode 100644 (file)
index 0000000..5bbc7df
--- /dev/null
@@ -0,0 +1,59 @@
+From c09b90cc8c2a8a31e8ce7134be73979c141cd639 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Sep 2022 15:15:04 +0100
+Subject: powerpc/xmon: Fix -Wswitch-unreachable warning in bpt_cmds
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 1c4a4a4c8410be4a231a58b23e7a30923ff954ac ]
+
+When building with automatic stack variable initialization, GCC 12
+complains about variables defined outside of switch case statements.
+Move the variable into the case that uses it, which silences the warning:
+
+arch/powerpc/xmon/xmon.c: In function ‘bpt_cmds’:
+arch/powerpc/xmon/xmon.c:1529:13: warning: statement will never be executed [-Wswitch-unreachable]
+ 1529 |         int mode;
+      |             ^~~~
+
+Fixes: 09b6c1129f89 ("powerpc/xmon: Fix compile error with PPC_8xx=y")
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/YySE6FHiOcbWWR+9@work
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/xmon/xmon.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
+index c6a36b4045e8..2872b66d9fec 100644
+--- a/arch/powerpc/xmon/xmon.c
++++ b/arch/powerpc/xmon/xmon.c
+@@ -1433,9 +1433,9 @@ bpt_cmds(void)
+       cmd = inchar();
+       switch (cmd) {
+-      static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
+-      int mode;
+-      case 'd':       /* bd - hardware data breakpoint */
++      case 'd': {     /* bd - hardware data breakpoint */
++              static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
++              int mode;
+               if (xmon_is_ro) {
+                       printf(xmon_ro_msg);
+                       break;
+@@ -1468,6 +1468,7 @@ bpt_cmds(void)
+               force_enable_xmon();
+               break;
++      }
+       case 'i':       /* bi - hardware instr breakpoint */
+               if (xmon_is_ro) {
+-- 
+2.35.1
+
diff --git a/queue-5.10/ppp-associate-skb-with-a-device-at-tx.patch b/queue-5.10/ppp-associate-skb-with-a-device-at-tx.patch
new file mode 100644 (file)
index 0000000..ea1e28f
--- /dev/null
@@ -0,0 +1,62 @@
+From 192ecaa1300a1130d9db4709c241c0f83f74ca2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 10:29:13 -0800
+Subject: ppp: associate skb with a device at tx
+
+From: Stanislav Fomichev <sdf@google.com>
+
+[ Upstream commit 9f225444467b98579cf28d94f4ad053460dfdb84 ]
+
+Syzkaller triggered flow dissector warning with the following:
+
+r0 = openat$ppp(0xffffffffffffff9c, &(0x7f0000000000), 0xc0802, 0x0)
+ioctl$PPPIOCNEWUNIT(r0, 0xc004743e, &(0x7f00000000c0))
+ioctl$PPPIOCSACTIVE(r0, 0x40107446, &(0x7f0000000240)={0x2, &(0x7f0000000180)=[{0x20, 0x0, 0x0, 0xfffff034}, {0x6}]})
+pwritev(r0, &(0x7f0000000040)=[{&(0x7f0000000140)='\x00!', 0x2}], 0x1, 0x0, 0x0)
+
+[    9.485814] WARNING: CPU: 3 PID: 329 at net/core/flow_dissector.c:1016 __skb_flow_dissect+0x1ee0/0x1fa0
+[    9.485929]  skb_get_poff+0x53/0xa0
+[    9.485937]  bpf_skb_get_pay_offset+0xe/0x20
+[    9.485944]  ? ppp_send_frame+0xc2/0x5b0
+[    9.485949]  ? _raw_spin_unlock_irqrestore+0x40/0x60
+[    9.485958]  ? __ppp_xmit_process+0x7a/0xe0
+[    9.485968]  ? ppp_xmit_process+0x5b/0xb0
+[    9.485974]  ? ppp_write+0x12a/0x190
+[    9.485981]  ? do_iter_write+0x18e/0x2d0
+[    9.485987]  ? __import_iovec+0x30/0x130
+[    9.485997]  ? do_pwritev+0x1b6/0x240
+[    9.486016]  ? trace_hardirqs_on+0x47/0x50
+[    9.486023]  ? __x64_sys_pwritev+0x24/0x30
+[    9.486026]  ? do_syscall_64+0x3d/0x80
+[    9.486031]  ? entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Flow dissector tries to find skb net namespace either via device
+or via socket. Neigher is set in ppp_send_frame, so let's manually
+use ppp->dev.
+
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: linux-ppp@vger.kernel.org
+Reported-by: syzbot+41cab52ab62ee99ed24a@syzkaller.appspotmail.com
+Signed-off-by: Stanislav Fomichev <sdf@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ppp/ppp_generic.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index 2b9815ec4a62..b825c6a9b6dd 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -1610,6 +1610,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
+       int len;
+       unsigned char *cp;
++      skb->dev = ppp->dev;
++
+       if (proto < 0x8000) {
+ #ifdef CONFIG_PPP_FILTER
+               /* check if we should pass this packet */
+-- 
+2.35.1
+
diff --git a/queue-5.10/proc-fixup-uptime-selftest.patch b/queue-5.10/proc-fixup-uptime-selftest.patch
new file mode 100644 (file)
index 0000000..76f4e1e
--- /dev/null
@@ -0,0 +1,48 @@
+From 38cd961168a6e3eb4dd1bd8654eefcd2ac061478 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Oct 2022 21:08:09 +0300
+Subject: proc: fixup uptime selftest
+
+From: Alexey Dobriyan <adobriyan@gmail.com>
+
+[ Upstream commit 5cc81d5c81af0dee54da9a67a3ebe4be076a13db ]
+
+syscall(3) returns -1 and sets errno on error, unlike "syscall"
+instruction.
+
+Systems which have <= 32/64 CPUs are unaffected. Test won't bounce
+to all CPUs before completing if there are more of them.
+
+Link: https://lkml.kernel.org/r/Y1bUiT7VRXlXPQa1@p183
+Fixes: 1f5bd0547654 ("proc: selftests: test /proc/uptime")
+Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/proc/proc-uptime-002.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/proc/proc-uptime-002.c b/tools/testing/selftests/proc/proc-uptime-002.c
+index e7ceabed7f51..7d0aa22bdc12 100644
+--- a/tools/testing/selftests/proc/proc-uptime-002.c
++++ b/tools/testing/selftests/proc/proc-uptime-002.c
+@@ -17,6 +17,7 @@
+ // while shifting across CPUs.
+ #undef NDEBUG
+ #include <assert.h>
++#include <errno.h>
+ #include <unistd.h>
+ #include <sys/syscall.h>
+ #include <stdlib.h>
+@@ -54,7 +55,7 @@ int main(void)
+               len += sizeof(unsigned long);
+               free(m);
+               m = malloc(len);
+-      } while (sys_sched_getaffinity(0, len, m) == -EINVAL);
++      } while (sys_sched_getaffinity(0, len, m) == -1 && errno == EINVAL);
+       fd = open("/proc/uptime", O_RDONLY);
+       assert(fd >= 0);
+-- 
+2.35.1
+
diff --git a/queue-5.10/pstore-avoid-kcore-oops-by-vmap-ing-with-vm_ioremap.patch b/queue-5.10/pstore-avoid-kcore-oops-by-vmap-ing-with-vm_ioremap.patch
new file mode 100644 (file)
index 0000000..de6f64a
--- /dev/null
@@ -0,0 +1,103 @@
+From 8591d562e662ab30c6f0e9428ff67ad04f713d40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 15:31:36 -0800
+Subject: pstore: Avoid kcore oops by vmap()ing with VM_IOREMAP
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+[ Upstream commit e6b842741b4f39007215fd7e545cb55aa3d358a2 ]
+
+An oops can be induced by running 'cat /proc/kcore > /dev/null' on
+devices using pstore with the ram backend because kmap_atomic() assumes
+lowmem pages are accessible with __va().
+
+ Unable to handle kernel paging request at virtual address ffffff807ff2b000
+ Mem abort info:
+ ESR = 0x96000006
+ EC = 0x25: DABT (current EL), IL = 32 bits
+ SET = 0, FnV = 0
+ EA = 0, S1PTW = 0
+ FSC = 0x06: level 2 translation fault
+ Data abort info:
+ ISV = 0, ISS = 0x00000006
+ CM = 0, WnR = 0
+ swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000081d87000
+ [ffffff807ff2b000] pgd=180000017fe18003, p4d=180000017fe18003, pud=180000017fe18003, pmd=0000000000000000
+ Internal error: Oops: 96000006 [#1] PREEMPT SMP
+ Modules linked in: dm_integrity
+ CPU: 7 PID: 21179 Comm: perf Not tainted 5.15.67-10882-ge4eb2eb988cd #1 baa443fb8e8477896a370b31a821eb2009f9bfba
+ Hardware name: Google Lazor (rev3 - 8) (DT)
+ pstate: a0400009 (NzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : __memcpy+0x110/0x260
+ lr : vread+0x194/0x294
+ sp : ffffffc013ee39d0
+ x29: ffffffc013ee39f0 x28: 0000000000001000 x27: ffffff807ff2b000
+ x26: 0000000000001000 x25: ffffffc0085a2000 x24: ffffff802d4b3000
+ x23: ffffff80f8a60000 x22: ffffff802d4b3000 x21: ffffffc0085a2000
+ x20: ffffff8080b7bc68 x19: 0000000000001000 x18: 0000000000000000
+ x17: 0000000000000000 x16: 0000000000000000 x15: ffffffd3073f2e60
+ x14: ffffffffad588000 x13: 0000000000000000 x12: 0000000000000001
+ x11: 00000000000001a2 x10: 00680000fff2bf0b x9 : 03fffffff807ff2b
+ x8 : 0000000000000001 x7 : 0000000000000000 x6 : 0000000000000000
+ x5 : ffffff802d4b4000 x4 : ffffff807ff2c000 x3 : ffffffc013ee3a78
+ x2 : 0000000000001000 x1 : ffffff807ff2b000 x0 : ffffff802d4b3000
+ Call trace:
+ __memcpy+0x110/0x260
+ read_kcore+0x584/0x778
+ proc_reg_read+0xb4/0xe4
+
+During early boot, memblock reserves the pages for the ramoops reserved
+memory node in DT that would otherwise be part of the direct lowmem
+mapping. Pstore's ram backend reuses those reserved pages to change the
+memory type (writeback or non-cached) by passing the pages to vmap()
+(see pfn_to_page() usage in persistent_ram_vmap() for more details) with
+specific flags. When read_kcore() starts iterating over the vmalloc
+region, it runs over the virtual address that vmap() returned for
+ramoops. In aligned_vread() the virtual address is passed to
+vmalloc_to_page() which returns the page struct for the reserved lowmem
+area. That lowmem page is passed to kmap_atomic(), which effectively
+calls page_to_virt() that assumes a lowmem page struct must be directly
+accessible with __va() and friends. These pages are mapped via vmap()
+though, and the lowmem mapping was never made, so accessing them via the
+lowmem virtual address oopses like above.
+
+Let's side-step this problem by passing VM_IOREMAP to vmap(). This will
+tell vread() to not include the ramoops region in the kcore. Instead the
+area will look like a bunch of zeros. The alternative is to teach kmap()
+about vmalloc areas that intersect with lowmem. Presumably such a change
+isn't a one-liner, and there isn't much interest in inspecting the
+ramoops region in kcore files anyway, so the most expedient route is
+taken for now.
+
+Cc: Brian Geffon <bgeffon@google.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Fixes: 404a6043385d ("staging: android: persistent_ram: handle reserving and mapping memory")
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20221205233136.3420802-1-swboyd@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/pstore/ram_core.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
+index aa8e0b65ff1a..184cb97c83bd 100644
+--- a/fs/pstore/ram_core.c
++++ b/fs/pstore/ram_core.c
+@@ -425,7 +425,11 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size,
+               phys_addr_t addr = page_start + i * PAGE_SIZE;
+               pages[i] = pfn_to_page(addr >> PAGE_SHIFT);
+       }
+-      vaddr = vmap(pages, page_count, VM_MAP, prot);
++      /*
++       * VM_IOREMAP used here to bypass this region during vread()
++       * and kmap_atomic() (i.e. kcore) to avoid __va() failures.
++       */
++      vaddr = vmap(pages, page_count, VM_MAP | VM_IOREMAP, prot);
+       kfree(pages);
+       /*
+-- 
+2.35.1
+
diff --git a/queue-5.10/pstore-ram-fix-error-return-code-in-ramoops_probe.patch b/queue-5.10/pstore-ram-fix-error-return-code-in-ramoops_probe.patch
new file mode 100644 (file)
index 0000000..5ce59d4
--- /dev/null
@@ -0,0 +1,45 @@
+From 87524cb0ce2d879af123373cb43e6ce629b7656b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 16:22:54 +0800
+Subject: pstore/ram: Fix error return code in ramoops_probe()
+
+From: Wang Yufen <wangyufen@huawei.com>
+
+[ Upstream commit e1fce564900f8734edf15b87f028c57e14f6e28d ]
+
+In the if (dev_of_node(dev) && !pdata) path, the "err" may be assigned a
+value of 0, so the error return code -EINVAL may be incorrectly set
+to 0. To fix set valid return code before calling to goto.
+
+Fixes: 35da60941e44 ("pstore/ram: add Device Tree bindings")
+Signed-off-by: Wang Yufen <wangyufen@huawei.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/1669969374-46582-1-git-send-email-wangyufen@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/pstore/ram.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
+index ca6d8a867285..98e579ce0d63 100644
+--- a/fs/pstore/ram.c
++++ b/fs/pstore/ram.c
+@@ -730,6 +730,7 @@ static int ramoops_probe(struct platform_device *pdev)
+       /* Make sure we didn't get bogus platform data pointer. */
+       if (!pdata) {
+               pr_err("NULL platform data\n");
++              err = -EINVAL;
+               goto fail_out;
+       }
+@@ -737,6 +738,7 @@ static int ramoops_probe(struct platform_device *pdev)
+                       !pdata->ftrace_size && !pdata->pmsg_size)) {
+               pr_err("The memory size and the record/console size must be "
+                       "non-zero\n");
++              err = -EINVAL;
+               goto fail_out;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/pwm-sifive-call-pwm_sifive_update_clock-while-mutex-.patch b/queue-5.10/pwm-sifive-call-pwm_sifive_update_clock-while-mutex-.patch
new file mode 100644 (file)
index 0000000..b960db2
--- /dev/null
@@ -0,0 +1,50 @@
+From f0b1e341a5665c5f97c94f4f07a1fc6fcb54d3e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 19:35:05 +0100
+Subject: pwm: sifive: Call pwm_sifive_update_clock() while mutex is held
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 45558b3abb87eeb2cedb8a59cb2699c120b5102a ]
+
+As was documented in commit 0f02f491b786 ("pwm: sifive: Reduce time the
+controller lock is held") a caller of pwm_sifive_update_clock() must
+hold the mutex. So fix pwm_sifive_clock_notifier() to grab the lock.
+
+While this necessity was only documented later, the race exists since
+the driver was introduced.
+
+Fixes: 9e37a53eb051 ("pwm: sifive: Add a driver for SiFive SoC PWM")
+Reported-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Link: https://lore.kernel.org/r/20221018061656.1428111-1-u.kleine-koenig@pengutronix.de
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-sifive.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
+index 9cc0612f0849..12e9e23272ab 100644
+--- a/drivers/pwm/pwm-sifive.c
++++ b/drivers/pwm/pwm-sifive.c
+@@ -217,8 +217,11 @@ static int pwm_sifive_clock_notifier(struct notifier_block *nb,
+       struct pwm_sifive_ddata *ddata =
+               container_of(nb, struct pwm_sifive_ddata, notifier);
+-      if (event == POST_RATE_CHANGE)
++      if (event == POST_RATE_CHANGE) {
++              mutex_lock(&ddata->lock);
+               pwm_sifive_update_clock(ddata, ndata->new_rate);
++              mutex_unlock(&ddata->lock);
++      }
+       return NOTIFY_OK;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/pwm-tegra-improve-required-rate-calculation.patch b/queue-5.10/pwm-tegra-improve-required-rate-calculation.patch
new file mode 100644 (file)
index 0000000..ce309eb
--- /dev/null
@@ -0,0 +1,52 @@
+From 353f150f4886d833958b83c50993b0a600d40000 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Oct 2022 13:33:55 +0100
+Subject: pwm: tegra: Improve required rate calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jon Hunter <jonathanh@nvidia.com>
+
+[ Upstream commit f271946117dde2ca8741b8138b347b2d68e6ad56 ]
+
+For the case where dev_pm_opp_set_rate() is called to set the PWM clock
+rate, the requested rate is calculated as ...
+
+ required_clk_rate = (NSEC_PER_SEC / period_ns) << PWM_DUTY_WIDTH;
+
+The above calculation may lead to rounding errors because the
+NSEC_PER_SEC is divided by 'period_ns' before applying the
+PWM_DUTY_WIDTH multiplication factor. For example, if the period is
+45334ns, the above calculation yields a rate of 5646848Hz instead of
+5646976Hz. Fix this by applying the multiplication factor before
+dividing and using the DIV_ROUND_UP macro which yields the expected
+result of 5646976Hz.
+
+Fixes: 1d7796bdb63a ("pwm: tegra: Support dynamic clock frequency configuration")
+Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-tegra.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
+index 8c4e6657b61e..36cc1452cb7a 100644
+--- a/drivers/pwm/pwm-tegra.c
++++ b/drivers/pwm/pwm-tegra.c
+@@ -142,8 +142,8 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                * source clock rate as required_clk_rate, PWM controller will
+                * be able to configure the requested period.
+                */
+-              required_clk_rate =
+-                      (NSEC_PER_SEC / period_ns) << PWM_DUTY_WIDTH;
++              required_clk_rate = DIV_ROUND_UP_ULL(NSEC_PER_SEC << PWM_DUTY_WIDTH,
++                                                   period_ns);
+               err = clk_set_rate(pc->clk, required_clk_rate);
+               if (err < 0)
+-- 
+2.35.1
+
diff --git a/queue-5.10/qed-gcc13-use-u16-for-fid-to-be-big-enough.patch b/queue-5.10/qed-gcc13-use-u16-for-fid-to-be-big-enough.patch
new file mode 100644 (file)
index 0000000..ddd3f75
--- /dev/null
@@ -0,0 +1,53 @@
+From cf20fa31a495bca7381ac522382ee627a656a7b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Oct 2022 12:43:54 +0100
+Subject: qed (gcc13): use u16 for fid to be big enough
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit 7d84118229bf7f7290438c85caa8e49de52d50c1 ]
+
+gcc 13 correctly reports overflow in qed_grc_dump_addr_range():
+In file included from drivers/net/ethernet/qlogic/qed/qed.h:23,
+                 from drivers/net/ethernet/qlogic/qed/qed_debug.c:10:
+drivers/net/ethernet/qlogic/qed/qed_debug.c: In function 'qed_grc_dump_addr_range':
+include/linux/qed/qed_if.h:1217:9: error: overflow in conversion from 'int' to 'u8' {aka 'unsigned char'} changes value from '(int)vf_id << 8 | 128' to '128' [-Werror=overflow]
+
+We do:
+  u8 fid;
+  ...
+  fid = vf_id << 8 | 128;
+
+Since fid is 16bit (and the stored value above too), fid should be u16,
+not u8. Fix that.
+
+Cc: Martin Liska <mliska@suse.cz>
+Cc: Ariel Elior <aelior@marvell.com>
+Cc: Manish Chopra <manishc@marvell.com>
+Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20221031114354.10398-1-jirislaby@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qlogic/qed/qed_debug.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+index 6ab3e60d4928..4b4077cf2d26 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+@@ -1796,9 +1796,10 @@ static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn,
+                                  u8 split_id)
+ {
+       struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
+-      u8 port_id = 0, pf_id = 0, vf_id = 0, fid = 0;
++      u8 port_id = 0, pf_id = 0, vf_id = 0;
+       bool read_using_dmae = false;
+       u32 thresh;
++      u16 fid;
+       if (!dump)
+               return len;
+-- 
+2.35.1
+
diff --git a/queue-5.10/r6040-fix-kmemleak-in-probe-and-remove.patch b/queue-5.10/r6040-fix-kmemleak-in-probe-and-remove.patch
new file mode 100644 (file)
index 0000000..273bbd4
--- /dev/null
@@ -0,0 +1,96 @@
+From c63b0118554ecab7259e964d75e1b4a7b9450043 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Dec 2022 20:56:14 +0800
+Subject: r6040: Fix kmemleak in probe and remove
+
+From: Li Zetao <lizetao1@huawei.com>
+
+[ Upstream commit 7e43039a49c2da45edc1d9d7c9ede4003ab45a5f ]
+
+There is a memory leaks reported by kmemleak:
+
+  unreferenced object 0xffff888116111000 (size 2048):
+    comm "modprobe", pid 817, jiffies 4294759745 (age 76.502s)
+    hex dump (first 32 bytes):
+      00 c4 0a 04 81 88 ff ff 08 10 11 16 81 88 ff ff  ................
+      08 10 11 16 81 88 ff ff 00 00 00 00 00 00 00 00  ................
+    backtrace:
+      [<ffffffff815bcd82>] kmalloc_trace+0x22/0x60
+      [<ffffffff827e20ee>] phy_device_create+0x4e/0x90
+      [<ffffffff827e6072>] get_phy_device+0xd2/0x220
+      [<ffffffff827e7844>] mdiobus_scan+0xa4/0x2e0
+      [<ffffffff827e8be2>] __mdiobus_register+0x482/0x8b0
+      [<ffffffffa01f5d24>] r6040_init_one+0x714/0xd2c [r6040]
+      ...
+
+The problem occurs in probe process as follows:
+  r6040_init_one:
+    mdiobus_register
+      mdiobus_scan    <- alloc and register phy_device,
+                         the reference count of phy_device is 3
+    r6040_mii_probe
+      phy_connect     <- connect to the first phy_device,
+                         so the reference count of the first
+                         phy_device is 4, others are 3
+    register_netdev   <- fault inject succeeded, goto error handling path
+
+    // error handling path
+    err_out_mdio_unregister:
+      mdiobus_unregister(lp->mii_bus);
+    err_out_mdio:
+      mdiobus_free(lp->mii_bus);    <- the reference count of the first
+                                       phy_device is 1, it is not released
+                                       and other phy_devices are released
+  // similarly, the remove process also has the same problem
+
+The root cause is traced to the phy_device is not disconnected when
+removes one r6040 device in r6040_remove_one() or on error handling path
+after r6040_mii probed successfully. In r6040_mii_probe(), a net ethernet
+device is connected to the first PHY device of mii_bus, in order to
+notify the connected driver when the link status changes, which is the
+default behavior of the PHY infrastructure to handle everything.
+Therefore the phy_device should be disconnected when removes one r6040
+device or on error handling path.
+
+Fix it by adding phy_disconnect() when removes one r6040 device or on
+error handling path after r6040_mii probed successfully.
+
+Fixes: 3831861b4ad8 ("r6040: implement phylib")
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Link: https://lore.kernel.org/r/20221213125614.927754-1-lizetao1@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/rdc/r6040.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
+index ccdfa930130b..4cff544f04c2 100644
+--- a/drivers/net/ethernet/rdc/r6040.c
++++ b/drivers/net/ethernet/rdc/r6040.c
+@@ -1158,10 +1158,12 @@ static int r6040_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+       err = register_netdev(dev);
+       if (err) {
+               dev_err(&pdev->dev, "Failed to register net device\n");
+-              goto err_out_mdio_unregister;
++              goto err_out_phy_disconnect;
+       }
+       return 0;
++err_out_phy_disconnect:
++      phy_disconnect(dev->phydev);
+ err_out_mdio_unregister:
+       mdiobus_unregister(lp->mii_bus);
+ err_out_mdio:
+@@ -1185,6 +1187,7 @@ static void r6040_remove_one(struct pci_dev *pdev)
+       struct r6040_private *lp = netdev_priv(dev);
+       unregister_netdev(dev);
++      phy_disconnect(dev->phydev);
+       mdiobus_unregister(lp->mii_bus);
+       mdiobus_free(lp->mii_bus);
+       netif_napi_del(&lp->napi);
+-- 
+2.35.1
+
diff --git a/queue-5.10/rapidio-devices-fix-missing-put_device-in-mport_cdev.patch b/queue-5.10/rapidio-devices-fix-missing-put_device-in-mport_cdev.patch
new file mode 100644 (file)
index 0000000..b0e1934
--- /dev/null
@@ -0,0 +1,44 @@
+From f41a5bc0494da607d9f9a5f46568a15e8b1a9d7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Dec 2022 08:57:21 +0000
+Subject: rapidio: devices: fix missing put_device in mport_cdev_open
+
+From: Cai Xinchen <caixinchen1@huawei.com>
+
+[ Upstream commit d5b6e6eba3af11cb2a2791fa36a2524990fcde1a ]
+
+When kfifo_alloc fails, the refcount of chdev->dev is left incremental.
+We should use put_device(&chdev->dev) to decrease the ref count of
+chdev->dev to avoid refcount leak.
+
+Link: https://lkml.kernel.org/r/20221203085721.13146-1-caixinchen1@huawei.com
+Fixes: e8de370188d0 ("rapidio: add mport char device driver")
+Signed-off-by: Cai Xinchen <caixinchen1@huawei.com>
+Cc: Alexandre Bounine <alex.bou9@gmail.com>
+Cc: Dan Carpenter <error27@gmail.com>
+Cc: Jakob Koschel <jakobkoschel@gmail.com>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Matt Porter <mporter@kernel.crashing.org>
+Cc: Wang Weiyang <wangweiyang2@huawei.com>
+Cc: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rapidio/devices/rio_mport_cdev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c
+index b8c09eaa23b5..5ac2dc1e2abd 100644
+--- a/drivers/rapidio/devices/rio_mport_cdev.c
++++ b/drivers/rapidio/devices/rio_mport_cdev.c
+@@ -1911,6 +1911,7 @@ static int mport_cdev_open(struct inode *inode, struct file *filp)
+                         sizeof(struct rio_event) * MPORT_EVENT_DEPTH,
+                         GFP_KERNEL);
+       if (ret < 0) {
++              put_device(&chdev->dev);
+               dev_err(&chdev->dev, DRV_NAME ": kfifo_alloc failed\n");
+               ret = -ENOMEM;
+               goto err_fifo;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rapidio-fix-possible-name-leaks-when-rio_add_device-.patch b/queue-5.10/rapidio-fix-possible-name-leaks-when-rio_add_device-.patch
new file mode 100644 (file)
index 0000000..38855c8
--- /dev/null
@@ -0,0 +1,76 @@
+From 83beaf9944431686092ffc0b703f9b9cb56f1eba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 23:26:35 +0800
+Subject: rapidio: fix possible name leaks when rio_add_device() fails
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit f9574cd48679926e2a569e1957a5a1bcc8a719ac ]
+
+Patch series "rapidio: fix three possible memory leaks".
+
+This patchset fixes three name leaks in error handling.
+ - patch #1 fixes two name leaks while rio_add_device() fails.
+ - patch #2 fixes a name leak while  rio_register_mport() fails.
+
+This patch (of 2):
+
+If rio_add_device() returns error, the name allocated by dev_set_name()
+need be freed.  It should use put_device() to give up the reference in the
+error path, so that the name can be freed in kobject_cleanup(), and the
+'rdev' can be freed in rio_release_dev().
+
+Link: https://lkml.kernel.org/r/20221114152636.2939035-1-yangyingliang@huawei.com
+Link: https://lkml.kernel.org/r/20221114152636.2939035-2-yangyingliang@huawei.com
+Fixes: e8de370188d0 ("rapidio: add mport char device driver")
+Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Cc: Alexandre Bounine <alex.bou9@gmail.com>
+Cc: Matt Porter <mporter@kernel.crashing.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rapidio/devices/rio_mport_cdev.c | 7 +++++--
+ drivers/rapidio/rio-scan.c               | 8 ++++++--
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c
+index 94331d999d27..48cd9b7f3b89 100644
+--- a/drivers/rapidio/devices/rio_mport_cdev.c
++++ b/drivers/rapidio/devices/rio_mport_cdev.c
+@@ -1803,8 +1803,11 @@ static int rio_mport_add_riodev(struct mport_cdev_priv *priv,
+               rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
+                                  0, 0xffff);
+       err = rio_add_device(rdev);
+-      if (err)
+-              goto cleanup;
++      if (err) {
++              put_device(&rdev->dev);
++              return err;
++      }
++
+       rio_dev_get(rdev);
+       return 0;
+diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
+index 19b0c33f4a62..fdcf742b2adb 100644
+--- a/drivers/rapidio/rio-scan.c
++++ b/drivers/rapidio/rio-scan.c
+@@ -454,8 +454,12 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
+                                  0, 0xffff);
+       ret = rio_add_device(rdev);
+-      if (ret)
+-              goto cleanup;
++      if (ret) {
++              if (rswitch)
++                      kfree(rswitch->route_table);
++              put_device(&rdev->dev);
++              return NULL;
++      }
+       rio_dev_get(rdev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/rapidio-fix-possible-uaf-when-kfifo_alloc-fails.patch b/queue-5.10/rapidio-fix-possible-uaf-when-kfifo_alloc-fails.patch
new file mode 100644 (file)
index 0000000..95cb56a
--- /dev/null
@@ -0,0 +1,58 @@
+From 16775613ad82a13a8fce0cf08fb83581a2aecb7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 17:51:47 +0800
+Subject: rapidio: fix possible UAF when kfifo_alloc() fails
+
+From: Wang Weiyang <wangweiyang2@huawei.com>
+
+[ Upstream commit 02d7d89f816951e0862147d751b1150d67aaebdd ]
+
+If kfifo_alloc() fails in mport_cdev_open(), goto err_fifo and just free
+priv. But priv is still in the chdev->file_list, then list traversal
+may cause UAF. This fixes the following smatch warning:
+
+drivers/rapidio/devices/rio_mport_cdev.c:1930 mport_cdev_open() warn: '&priv->list' not removed from list
+
+Link: https://lkml.kernel.org/r/20221123095147.52408-1-wangweiyang2@huawei.com
+Fixes: e8de370188d0 ("rapidio: add mport char device driver")
+Signed-off-by: Wang Weiyang <wangweiyang2@huawei.com>
+Cc: Alexandre Bounine <alex.bou9@gmail.com>
+Cc: Dan Carpenter <error27@gmail.com>
+Cc: Jakob Koschel <jakobkoschel@gmail.com>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Matt Porter <mporter@kernel.crashing.org>
+Cc: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rapidio/devices/rio_mport_cdev.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c
+index 48cd9b7f3b89..b8c09eaa23b5 100644
+--- a/drivers/rapidio/devices/rio_mport_cdev.c
++++ b/drivers/rapidio/devices/rio_mport_cdev.c
+@@ -1903,10 +1903,6 @@ static int mport_cdev_open(struct inode *inode, struct file *filp)
+       priv->md = chdev;
+-      mutex_lock(&chdev->file_mutex);
+-      list_add_tail(&priv->list, &chdev->file_list);
+-      mutex_unlock(&chdev->file_mutex);
+-
+       INIT_LIST_HEAD(&priv->db_filters);
+       INIT_LIST_HEAD(&priv->pw_filters);
+       spin_lock_init(&priv->fifo_lock);
+@@ -1925,6 +1921,9 @@ static int mport_cdev_open(struct inode *inode, struct file *filp)
+       spin_lock_init(&priv->req_lock);
+       mutex_init(&priv->dma_lock);
+ #endif
++      mutex_lock(&chdev->file_mutex);
++      list_add_tail(&priv->list, &chdev->file_list);
++      mutex_unlock(&chdev->file_mutex);
+       filp->private_data = priv;
+       goto out;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rapidio-rio-fix-possible-name-leak-in-rio_register_m.patch b/queue-5.10/rapidio-rio-fix-possible-name-leak-in-rio_register_m.patch
new file mode 100644 (file)
index 0000000..3e2d6df
--- /dev/null
@@ -0,0 +1,51 @@
+From 599571a6da492d072e12153ce8972f2e4e883c68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 23:26:36 +0800
+Subject: rapidio: rio: fix possible name leak in rio_register_mport()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit e92a216d16bde65d21a3227e0fb2aa0794576525 ]
+
+If device_register() returns error, the name allocated by dev_set_name()
+need be freed.  It should use put_device() to give up the reference in the
+error path, so that the name can be freed in kobject_cleanup(), and
+list_del() is called to delete the port from rio_mports.
+
+Link: https://lkml.kernel.org/r/20221114152636.2939035-3-yangyingliang@huawei.com
+Fixes: 2aaf308b95b2 ("rapidio: rework device hierarchy and introduce mport class of devices")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Cc: Alexandre Bounine <alex.bou9@gmail.com>
+Cc: Matt Porter <mporter@kernel.crashing.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rapidio/rio.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
+index 606986c5ba2c..fcab174e5888 100644
+--- a/drivers/rapidio/rio.c
++++ b/drivers/rapidio/rio.c
+@@ -2267,11 +2267,16 @@ int rio_register_mport(struct rio_mport *port)
+       atomic_set(&port->state, RIO_DEVICE_RUNNING);
+       res = device_register(&port->dev);
+-      if (res)
++      if (res) {
+               dev_err(&port->dev, "RIO: mport%d registration failed ERR=%d\n",
+                       port->id, res);
+-      else
++              mutex_lock(&rio_mport_list_lock);
++              list_del(&port->node);
++              mutex_unlock(&rio_mport_list_lock);
++              put_device(&port->dev);
++      } else {
+               dev_dbg(&port->dev, "RIO: registered mport%d\n", port->id);
++      }
+       return res;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/rcu-fix-__this_cpu_read-lockdep-warning-in-rcu_force.patch b/queue-5.10/rcu-fix-__this_cpu_read-lockdep-warning-in-rcu_force.patch
new file mode 100644 (file)
index 0000000..d356d3c
--- /dev/null
@@ -0,0 +1,60 @@
+From 55e22635041022d08dfa67dc6c0a5b29d51056ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Oct 2022 12:41:48 +0800
+Subject: rcu: Fix __this_cpu_read() lockdep warning in
+ rcu_force_quiescent_state()
+
+From: Zqiang <qiang1.zhang@intel.com>
+
+[ Upstream commit ceb1c8c9b8aa9199da46a0f29d2d5f08d9b44c15 ]
+
+Running rcutorture with non-zero fqs_duration module parameter in a
+kernel built with CONFIG_PREEMPTION=y results in the following splat:
+
+BUG: using __this_cpu_read() in preemptible [00000000]
+code: rcu_torture_fqs/398
+caller is __this_cpu_preempt_check+0x13/0x20
+CPU: 3 PID: 398 Comm: rcu_torture_fqs Not tainted 6.0.0-rc1-yoctodev-standard+
+Call Trace:
+<TASK>
+dump_stack_lvl+0x5b/0x86
+dump_stack+0x10/0x16
+check_preemption_disabled+0xe5/0xf0
+__this_cpu_preempt_check+0x13/0x20
+rcu_force_quiescent_state.part.0+0x1c/0x170
+rcu_force_quiescent_state+0x1e/0x30
+rcu_torture_fqs+0xca/0x160
+? rcu_torture_boost+0x430/0x430
+kthread+0x192/0x1d0
+? kthread_complete_and_exit+0x30/0x30
+ret_from_fork+0x22/0x30
+</TASK>
+
+The problem is that rcu_force_quiescent_state() uses __this_cpu_read()
+in preemptible code instead of the proper raw_cpu_read().  This commit
+therefore changes __this_cpu_read() to raw_cpu_read().
+
+Signed-off-by: Zqiang <qiang1.zhang@intel.com>
+Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tree.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index b10d6bcea77d..3fe7c75c371b 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -2650,7 +2650,7 @@ void rcu_force_quiescent_state(void)
+       struct rcu_node *rnp_old = NULL;
+       /* Funnel through hierarchy to reduce memory contention. */
+-      rnp = __this_cpu_read(rcu_data.mynode);
++      rnp = raw_cpu_read(rcu_data.mynode);
+       for (; rnp != NULL; rnp = rnp->parent) {
+               ret = (READ_ONCE(rcu_state.gp_flags) & RCU_GP_FLAG_FQS) ||
+                      !raw_spin_trylock(&rnp->fqslock);
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-core-fix-order-of-nldev_exit-call.patch b/queue-5.10/rdma-core-fix-order-of-nldev_exit-call.patch
new file mode 100644 (file)
index 0000000..19ad504
--- /dev/null
@@ -0,0 +1,38 @@
+From e016afd6361853686b2c8897cc8eb5d50670b852 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Oct 2022 10:37:13 +0300
+Subject: RDMA/core: Fix order of nldev_exit call
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 4508d32ccced24c972bc4592104513e1ff8439b5 ]
+
+Create symmetrical exit flow by calling to nldev_exit() after
+call to rdma_nl_unregister(RDMA_NL_LS).
+
+Fixes: 6c80b41abe22 ("RDMA/netlink: Add nldev initialization flows")
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Link: https://lore.kernel.org/r/64e676774a53a406f4cde265d5a4cfd6b8e97df9.1666683334.git.leonro@nvidia.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+index d91892ffe243..5b7abcf102fe 100644
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -2793,8 +2793,8 @@ static int __init ib_core_init(void)
+ static void __exit ib_core_cleanup(void)
+ {
+       roce_gid_mgmt_cleanup();
+-      nldev_exit();
+       rdma_nl_unregister(RDMA_NL_LS);
++      nldev_exit();
+       unregister_pernet_device(&rdma_dev_net_ops);
+       unregister_blocking_lsm_notifier(&ibdev_lsm_nb);
+       ib_sa_cleanup();
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-hfi-decrease-pci-device-reference-count-in-erro.patch b/queue-5.10/rdma-hfi-decrease-pci-device-reference-count-in-erro.patch
new file mode 100644 (file)
index 0000000..cf0652e
--- /dev/null
@@ -0,0 +1,42 @@
+From e322ee62bc79edfd2307a476d7fe2614845e4002 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 21:15:46 +0800
+Subject: RDMA/hfi: Decrease PCI device reference count in error path
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit 9b51d072da1d27e1193e84708201c48e385ad912 ]
+
+pci_get_device() will increase the reference count for the returned
+pci_dev, and also decrease the reference count for the input parameter
+*from* if it is not NULL.
+
+If we break out the loop in node_affinity_init() with 'dev' not NULL, we
+need to call pci_dev_put() to decrease the reference count. Add missing
+pci_dev_put() in error path.
+
+Fixes: c513de490f80 ("IB/hfi1: Invalid NUMA node information can cause a divide by zero")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Link: https://lore.kernel.org/r/20221117131546.113280-1-wangxiongfeng2@huawei.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/affinity.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/infiniband/hw/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c
+index 04b1e8f021f6..d5a8d0173709 100644
+--- a/drivers/infiniband/hw/hfi1/affinity.c
++++ b/drivers/infiniband/hw/hfi1/affinity.c
+@@ -219,6 +219,8 @@ int node_affinity_init(void)
+       for (node = 0; node < node_affinity.num_possible_nodes; node++)
+               hfi1_per_node_cntr[node] = 1;
++      pci_dev_put(dev);
++
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-hfi1-fix-error-return-code-in-parse_platform_co.patch b/queue-5.10/rdma-hfi1-fix-error-return-code-in-parse_platform_co.patch
new file mode 100644 (file)
index 0000000..7c037e8
--- /dev/null
@@ -0,0 +1,78 @@
+From d1b9cbb099907c376d4d2adb13665d32bd8165ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 12:00:37 +0800
+Subject: RDMA/hfi1: Fix error return code in parse_platform_config()
+
+From: Wang Yufen <wangyufen@huawei.com>
+
+[ Upstream commit 725349f8ba1e78a146c6ff8f3ee5e2712e517106 ]
+
+In the previous iteration of the while loop, the "ret" may have been
+assigned a value of 0, so the error return code -EINVAL may have been
+incorrectly set to 0. To fix set valid return code before calling to
+goto.
+
+Fixes: 97167e813415 ("staging/rdma/hfi1: Tune for unknown channel if configuration file is absent")
+Signed-off-by: Wang Yufen <wangyufen@huawei.com>
+Link: https://lore.kernel.org/r/1669953638-11747-1-git-send-email-wangyufen@huawei.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/firmware.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/infiniband/hw/hfi1/firmware.c b/drivers/infiniband/hw/hfi1/firmware.c
+index 2cf102b5abd4..f3e64c850aa5 100644
+--- a/drivers/infiniband/hw/hfi1/firmware.c
++++ b/drivers/infiniband/hw/hfi1/firmware.c
+@@ -1786,6 +1786,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+       if (!dd->platform_config.data) {
+               dd_dev_err(dd, "%s: Missing config file\n", __func__);
++              ret = -EINVAL;
+               goto bail;
+       }
+       ptr = (u32 *)dd->platform_config.data;
+@@ -1794,6 +1795,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+       ptr++;
+       if (magic_num != PLATFORM_CONFIG_MAGIC_NUM) {
+               dd_dev_err(dd, "%s: Bad config file\n", __func__);
++              ret = -EINVAL;
+               goto bail;
+       }
+@@ -1817,6 +1819,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+       if (file_length > dd->platform_config.size) {
+               dd_dev_info(dd, "%s:File claims to be larger than read size\n",
+                           __func__);
++              ret = -EINVAL;
+               goto bail;
+       } else if (file_length < dd->platform_config.size) {
+               dd_dev_info(dd,
+@@ -1837,6 +1840,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+                       dd_dev_err(dd, "%s: Failed validation at offset %ld\n",
+                                  __func__, (ptr - (u32 *)
+                                             dd->platform_config.data));
++                      ret = -EINVAL;
+                       goto bail;
+               }
+@@ -1880,6 +1884,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+                                          __func__, table_type,
+                                          (ptr - (u32 *)
+                                           dd->platform_config.data));
++                              ret = -EINVAL;
+                               goto bail; /* We don't trust this file now */
+                       }
+                       pcfgcache->config_tables[table_type].table = ptr;
+@@ -1899,6 +1904,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+                                          __func__, table_type,
+                                          (ptr -
+                                           (u32 *)dd->platform_config.data));
++                              ret = -EINVAL;
+                               goto bail; /* We don't trust this file now */
+                       }
+                       pcfgcache->config_tables[table_type].table_metadata =
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-hns-fix-ext_sge-num-error-when-post-send.patch b/queue-5.10/rdma-hns-fix-ext_sge-num-error-when-post-send.patch
new file mode 100644 (file)
index 0000000..cafda26
--- /dev/null
@@ -0,0 +1,69 @@
+From 5b63656cf37d8e8d9294ad37beaa3bbc74e8b827 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 21:38:46 +0800
+Subject: RDMA/hns: Fix ext_sge num error when post send
+
+From: Luoyouming <luoyouming@huawei.com>
+
+[ Upstream commit 8eaa6f7d569b4a22bfc1b0a3fdfeeb401feb65a4 ]
+
+In the HNS ROCE driver, The sge is divided into standard sge and extended
+sge.  There are 2 standard sge in RC/XRC, and the UD standard sge is 0.
+In the scenario of RC SQ inline, if the data does not exceed 32bytes, the
+standard sge will be used. If it exceeds, only the extended sge will be
+used to fill the data.
+
+Currently, when filling the extended sge, max_gs is directly used as the
+number of the extended sge, which did not subtract the number of standard
+sge.  There is a logical error. The new algorithm subtracts the number of
+standard sge from max_gs to get the actual number of extended sge.
+
+Fixes: 30b707886aeb ("RDMA/hns: Support inline data in extented sge space for RC")
+Link: https://lore.kernel.org/r/20221108133847.2304539-2-xuhaoyue1@hisilicon.com
+Signed-off-by: Luoyouming <luoyouming@huawei.com>
+Signed-off-by: Haoyue Xu <xuhaoyue1@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 4836090ec817..e1395590edfd 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -154,20 +154,29 @@ static void set_atomic_seg(const struct ib_send_wr *wr,
+                      V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, valid_num_sge);
+ }
++static unsigned int get_std_sge_num(struct hns_roce_qp *qp)
++{
++      if (qp->ibqp.qp_type == IB_QPT_GSI || qp->ibqp.qp_type == IB_QPT_UD)
++              return 0;
++
++      return HNS_ROCE_SGE_IN_WQE;
++}
++
+ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+                                const struct ib_send_wr *wr,
+                                unsigned int *sge_idx, u32 msg_len)
+ {
+       struct ib_device *ibdev = &(to_hr_dev(qp->ibqp.device))->ib_dev;
+-      unsigned int ext_sge_sz = qp->sq.max_gs * HNS_ROCE_SGE_SIZE;
+       unsigned int left_len_in_pg;
+       unsigned int idx = *sge_idx;
++      unsigned int std_sge_num;
+       unsigned int i = 0;
+       unsigned int len;
+       void *addr;
+       void *dseg;
+-      if (msg_len > ext_sge_sz) {
++      std_sge_num = get_std_sge_num(qp);
++      if (msg_len > (qp->sq.max_gs - std_sge_num) * HNS_ROCE_SGE_SIZE) {
+               ibdev_err(ibdev,
+                         "no enough extended sge space for inline data.\n");
+               return -EINVAL;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-hns-fix-memory-leak-in-hns_roce_alloc_mr.patch b/queue-5.10/rdma-hns-fix-memory-leak-in-hns_roce_alloc_mr.patch
new file mode 100644 (file)
index 0000000..cf6d070
--- /dev/null
@@ -0,0 +1,41 @@
+From 8d1ca89b410bff50d99e0ad5f4fdbe508c3d6c76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Nov 2022 15:08:34 +0800
+Subject: RDMA/hns: fix memory leak in hns_roce_alloc_mr()
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit a115aa00b18f7b8982b8f458149632caf64a862a ]
+
+When hns_roce_mr_enable() failed in hns_roce_alloc_mr(), mr_key is not
+released. Compiled test only.
+
+Fixes: 9b2cf76c9f05 ("RDMA/hns: Optimize PBL buffer allocation process")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Link: https://lore.kernel.org/r/20221119070834.48502-1-shaozhengchao@huawei.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_mr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
+index 6d7cc724862f..1c342a7bd7df 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
+@@ -456,10 +456,10 @@ struct ib_mr *hns_roce_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
+       return &mr->ibmr;
+-err_key:
+-      free_mr_key(hr_dev, mr);
+ err_pbl:
+       free_mr_pbl(hr_dev, mr);
++err_key:
++      free_mr_key(hr_dev, mr);
+ err_free:
+       kfree(mr);
+       return ERR_PTR(ret);
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-hns-fix-page-size-cap-from-firmware.patch b/queue-5.10/rdma-hns-fix-page-size-cap-from-firmware.patch
new file mode 100644 (file)
index 0000000..b6c6d11
--- /dev/null
@@ -0,0 +1,39 @@
+From 8fd958b3acb62fb9467ac5e12310b0b0c545b031 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Nov 2022 18:29:09 +0800
+Subject: RDMA/hns: Fix page size cap from firmware
+
+From: Chengchang Tang <tangchengchang@huawei.com>
+
+[ Upstream commit 99dc5a0712883d5d13b620d25b3759d429577bc8 ]
+
+Add verification to make sure the roce page size cap is supported by the
+system page size.
+
+Fixes: ba6bb7e97421 ("RDMA/hns: Add interfaces to get pf capabilities from firmware")
+Link: https://lore.kernel.org/r/20221126102911.2921820-5-xuhaoyue1@hisilicon.com
+Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
+Signed-off-by: Haoyue Xu <xuhaoyue1@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 0f4ef4516868..76ed547b76ea 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -2166,6 +2166,9 @@ static int hns_roce_query_pf_caps(struct hns_roce_dev *hr_dev)
+       calc_pg_sz(caps->num_idx_segs, caps->idx_entry_sz, caps->idx_hop_num,
+                  1, &caps->idx_buf_pg_sz, &caps->idx_ba_pg_sz, HEM_TYPE_IDX);
++      if (!(caps->page_size_cap & PAGE_SIZE))
++              caps->page_size_cap = HNS_ROCE_V2_PAGE_SIZE_SUPPORTED;
++
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-hns-fix-pbl-page-mtr-find.patch b/queue-5.10/rdma-hns-fix-pbl-page-mtr-find.patch
new file mode 100644 (file)
index 0000000..a0b75cf
--- /dev/null
@@ -0,0 +1,41 @@
+From 3bc7fcd0f6ca2fa96193f19f23ddbe295f649525 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Nov 2022 18:29:08 +0800
+Subject: RDMA/hns: Fix PBL page MTR find
+
+From: Chengchang Tang <tangchengchang@huawei.com>
+
+[ Upstream commit 9fb39ef2ff3e18f1740625ba04093dfbef086d2b ]
+
+Now, The address of the first two pages in the MR will be searched, which
+use to speed up the lookup of the pbl table for hardware.  An exception
+will occur when there is only one page in this MR.  This patch fix the
+number of page to search.
+
+Fixes: 9b2cf76c9f05 ("RDMA/hns: Optimize PBL buffer allocation process")
+Link: https://lore.kernel.org/r/20221126102911.2921820-4-xuhaoyue1@hisilicon.com
+Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
+Signed-off-by: Haoyue Xu <xuhaoyue1@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index e1395590edfd..0f4ef4516868 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -2738,7 +2738,8 @@ static int set_mtpt_pbl(struct hns_roce_dev *hr_dev,
+       int i, count;
+       count = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages,
+-                                ARRAY_SIZE(pages), &pbl_ba);
++                                min_t(int, ARRAY_SIZE(pages), mr->npages),
++                                &pbl_ba);
+       if (count < 1) {
+               ibdev_err(ibdev, "failed to find PBL mtr, count = %d.\n",
+                         count);
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-hns-repacing-dseg_len-by-macros-in-fill_ext_sge.patch b/queue-5.10/rdma-hns-repacing-dseg_len-by-macros-in-fill_ext_sge.patch
new file mode 100644 (file)
index 0000000..33570d2
--- /dev/null
@@ -0,0 +1,57 @@
+From 5834ea5fd599cb0a155f5e76aa5e224adedefdb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Sep 2022 20:33:13 +0800
+Subject: RDMA/hns: Repacing 'dseg_len' by macros in fill_ext_sge_inl_data()
+
+From: Luoyouming <luoyouming@huawei.com>
+
+[ Upstream commit 3b1f864c904915b3baebffb31ea05ee704b0df3c ]
+
+The sge size is known to be constant, so it's unnecessary to use sizeof to
+calculate.
+
+Link: https://lore.kernel.org/r/20220922123315.3732205-11-xuhaoyue1@hisilicon.com
+Signed-off-by: Luoyouming <luoyouming@huawei.com>
+Signed-off-by: Haoyue Xu <xuhaoyue1@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: 8eaa6f7d569b ("RDMA/hns: Fix ext_sge num error when post send")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 6dab03b7aca8..4836090ec817 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -159,8 +159,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+                                unsigned int *sge_idx, u32 msg_len)
+ {
+       struct ib_device *ibdev = &(to_hr_dev(qp->ibqp.device))->ib_dev;
+-      unsigned int dseg_len = sizeof(struct hns_roce_v2_wqe_data_seg);
+-      unsigned int ext_sge_sz = qp->sq.max_gs * dseg_len;
++      unsigned int ext_sge_sz = qp->sq.max_gs * HNS_ROCE_SGE_SIZE;
+       unsigned int left_len_in_pg;
+       unsigned int idx = *sge_idx;
+       unsigned int i = 0;
+@@ -188,7 +187,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+               if (len <= left_len_in_pg) {
+                       memcpy(dseg, addr, len);
+-                      idx += len / dseg_len;
++                      idx += len / HNS_ROCE_SGE_SIZE;
+                       i++;
+                       if (i >= wr->num_sge)
+@@ -203,7 +202,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+                       len -= left_len_in_pg;
+                       addr += left_len_in_pg;
+-                      idx += left_len_in_pg / dseg_len;
++                      idx += left_len_in_pg / HNS_ROCE_SGE_SIZE;
+                       dseg = hns_roce_get_extend_sge(qp,
+                                               idx & (qp->sge.sge_cnt - 1));
+                       left_len_in_pg = 1 << HNS_HW_PAGE_SHIFT;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-nldev-add-checks-for-nla_nest_start-in-fill_sta.patch b/queue-5.10/rdma-nldev-add-checks-for-nla_nest_start-in-fill_sta.patch
new file mode 100644 (file)
index 0000000..2767e53
--- /dev/null
@@ -0,0 +1,38 @@
+From fe08097365343a4dbea3497b14dd17a4589069d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Nov 2022 04:34:10 +0000
+Subject: RDMA/nldev: Add checks for nla_nest_start() in
+ fill_stat_counter_qps()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit ea5ef136e215fdef35f14010bc51fcd6686e6922 ]
+
+As the nla_nest_start() may fail with NULL returned, the return value needs
+to be checked.
+
+Fixes: c4ffee7c9bdb ("RDMA/netlink: Implement counter dumpit calback")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Link: https://lore.kernel.org/r/20221126043410.85632-1-yuancan@huawei.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/nldev.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
+index f7689bc10d14..78534340d282 100644
+--- a/drivers/infiniband/core/nldev.c
++++ b/drivers/infiniband/core/nldev.c
+@@ -754,6 +754,8 @@ static int fill_stat_counter_qps(struct sk_buff *msg,
+       int ret = 0;
+       table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_QP);
++      if (!table_attr)
++              return -EMSGSIZE;
+       rt = &counter->device->res[RDMA_RESTRACK_QP];
+       xa_lock(&rt->xa);
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-nldev-fix-failure-to-send-large-messages.patch b/queue-5.10/rdma-nldev-fix-failure-to-send-large-messages.patch
new file mode 100644 (file)
index 0000000..ed07935
--- /dev/null
@@ -0,0 +1,38 @@
+From c17bf6a9e4733af653946d5f122ec39c2d8971f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 13:52:46 +0200
+Subject: RDMA/nldev: Fix failure to send large messages
+
+From: Mark Zhang <markzhang@nvidia.com>
+
+[ Upstream commit fc8f93ad3e5485d45c992233c96acd902992dfc4 ]
+
+Return "-EMSGSIZE" instead of "-EINVAL" when filling a QP entry, so that
+new SKBs will be allocated if there's not enough room in current SKB.
+
+Fixes: 65959522f806 ("RDMA: Add support to dump resource tracker in RAW format")
+Signed-off-by: Mark Zhang <markzhang@nvidia.com>
+Reviewed-by: Patrisious Haddad <phaddad@nvidia.com>
+Link: https://lore.kernel.org/r/b5e9c62f6b8369acab5648b661bf539cbceeffdc.1669636336.git.leonro@nvidia.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/nldev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
+index 78534340d282..f7f80707af4b 100644
+--- a/drivers/infiniband/core/nldev.c
++++ b/drivers/infiniband/core/nldev.c
+@@ -502,7 +502,7 @@ static int fill_res_qp_entry(struct sk_buff *msg, bool has_cap_net_admin,
+       /* In create_qp() port is not set yet */
+       if (qp->port && nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, qp->port))
+-              return -EINVAL;
++              return -EMSGSIZE;
+       ret = nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LQPN, qp->qp_num);
+       if (ret)
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-nldev-return-eagain-if-the-cm_id-isn-t-from-exp.patch b/queue-5.10/rdma-nldev-return-eagain-if-the-cm_id-isn-t-from-exp.patch
new file mode 100644 (file)
index 0000000..a2e605e
--- /dev/null
@@ -0,0 +1,51 @@
+From 878950364fd7983b95c5778fb1338de5b27ae2db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Nov 2022 10:51:36 +0200
+Subject: RDMA/nldev: Return "-EAGAIN" if the cm_id isn't from expected port
+
+From: Mark Zhang <markzhang@nvidia.com>
+
+[ Upstream commit ecacb3751f254572af0009b9501e2cdc83a30b6a ]
+
+When filling a cm_id entry, return "-EAGAIN" instead of 0 if the cm_id
+doesn'the have the same port as requested, otherwise an incomplete entry
+may be returned, which causes "rdam res show cm_id" to return an error.
+
+For example on a machine with two rdma devices with "rping -C 1 -v -s"
+running background, the "rdma" command fails:
+  $ rdma -V
+  rdma utility, iproute2-5.19.0
+  $ rdma res show cm_id
+  link mlx5_0/- cm-idn 0 state LISTEN ps TCP pid 28056 comm rping src-addr 0.0.0.0:7174
+  error: Protocol not available
+
+While with this fix it succeeds:
+  $ rdma res show cm_id
+  link mlx5_0/- cm-idn 0 state LISTEN ps TCP pid 26395 comm rping src-addr 0.0.0.0:7174
+  link mlx5_1/- cm-idn 0 state LISTEN ps TCP pid 26395 comm rping src-addr 0.0.0.0:7174
+
+Fixes: 00313983cda6 ("RDMA/nldev: provide detailed CM_ID information")
+Signed-off-by: Mark Zhang <markzhang@nvidia.com>
+Link: https://lore.kernel.org/r/a08e898cdac5e28428eb749a99d9d981571b8ea7.1667810736.git.leonro@nvidia.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/nldev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
+index c90f6378d839..f7689bc10d14 100644
+--- a/drivers/infiniband/core/nldev.c
++++ b/drivers/infiniband/core/nldev.c
+@@ -541,7 +541,7 @@ static int fill_res_cm_id_entry(struct sk_buff *msg, bool has_cap_net_admin,
+       struct rdma_cm_id *cm_id = &id_priv->id;
+       if (port && port != cm_id->port_num)
+-              return 0;
++              return -EAGAIN;
+       if (cm_id->port_num &&
+           nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, cm_id->port_num))
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-rxe-fix-null-ptr-deref-in-rxe_qp_do_cleanup-whe.patch b/queue-5.10/rdma-rxe-fix-null-ptr-deref-in-rxe_qp_do_cleanup-whe.patch
new file mode 100644 (file)
index 0000000..6100976
--- /dev/null
@@ -0,0 +1,78 @@
+From 49b5e8da8a361e34cbfc79a842ba8a29b382c4d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 23:14:37 +0800
+Subject: RDMA/rxe: Fix NULL-ptr-deref in rxe_qp_do_cleanup() when socket
+ create failed
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+[ Upstream commit f67376d801499f4fa0838c18c1efcad8840e550d ]
+
+There is a null-ptr-deref when mount.cifs over rdma:
+
+  BUG: KASAN: null-ptr-deref in rxe_qp_do_cleanup+0x2f3/0x360 [rdma_rxe]
+  Read of size 8 at addr 0000000000000018 by task mount.cifs/3046
+
+  CPU: 2 PID: 3046 Comm: mount.cifs Not tainted 6.1.0-rc5+ #62
+  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc3
+  Call Trace:
+   <TASK>
+   dump_stack_lvl+0x34/0x44
+   kasan_report+0xad/0x130
+   rxe_qp_do_cleanup+0x2f3/0x360 [rdma_rxe]
+   execute_in_process_context+0x25/0x90
+   __rxe_cleanup+0x101/0x1d0 [rdma_rxe]
+   rxe_create_qp+0x16a/0x180 [rdma_rxe]
+   create_qp.part.0+0x27d/0x340
+   ib_create_qp_kernel+0x73/0x160
+   rdma_create_qp+0x100/0x230
+   _smbd_get_connection+0x752/0x20f0
+   smbd_get_connection+0x21/0x40
+   cifs_get_tcp_session+0x8ef/0xda0
+   mount_get_conns+0x60/0x750
+   cifs_mount+0x103/0xd00
+   cifs_smb3_do_mount+0x1dd/0xcb0
+   smb3_get_tree+0x1d5/0x300
+   vfs_get_tree+0x41/0xf0
+   path_mount+0x9b3/0xdd0
+   __x64_sys_mount+0x190/0x1d0
+   do_syscall_64+0x35/0x80
+   entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+The root cause of the issue is the socket create failed in
+rxe_qp_init_req().
+
+So move the reset rxe_qp_do_cleanup() after the NULL ptr check.
+
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Link: https://lore.kernel.org/r/20221122151437.1057671-1-zhangxiaoxu5@huawei.com
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_qp.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index 2e4b008f0387..99c1b3553e6e 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -812,12 +812,12 @@ static void rxe_qp_do_cleanup(struct work_struct *work)
+               qp->resp.mr = NULL;
+       }
+-      if (qp_type(qp) == IB_QPT_RC)
+-              sk_dst_reset(qp->sk->sk);
+-
+       free_rd_atomic_resources(qp);
+       if (qp->sk) {
++              if (qp_type(qp) == IB_QPT_RC)
++                      sk_dst_reset(qp->sk->sk);
++
+               kernel_sock_shutdown(qp->sk, SHUT_RDWR);
+               sock_release(qp->sk);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-siw-fix-immediate-work-request-flush-to-complet.patch b/queue-5.10/rdma-siw-fix-immediate-work-request-flush-to-complet.patch
new file mode 100644 (file)
index 0000000..7d638f4
--- /dev/null
@@ -0,0 +1,137 @@
+From 9c0a3f6eed6e75910f990cc8063eb4c539a40985 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Nov 2022 15:50:57 +0100
+Subject: RDMA/siw: Fix immediate work request flush to completion queue
+
+From: Bernard Metzler <bmt@zurich.ibm.com>
+
+[ Upstream commit bdf1da5df9da680589a7f74448dd0a94dd3e1446 ]
+
+Correctly set send queue element opcode during immediate work request
+flushing in post sendqueue operation, if the QP is in ERROR state.
+An undefined ocode value results in out-of-bounds access to an array
+for mapping the opcode between siw internal and RDMA core representation
+in work completion generation. It resulted in a KASAN BUG report
+of type 'global-out-of-bounds' during NFSoRDMA testing.
+
+This patch further fixes a potential case of a malicious user which may
+write undefined values for completion queue elements status or opcode,
+if the CQ is memory mapped to user land. It avoids the same out-of-bounds
+access to arrays for status and opcode mapping as described above.
+
+Fixes: 303ae1cdfdf7 ("rdma/siw: application interface")
+Fixes: b0fff7317bb4 ("rdma/siw: completion queue methods")
+Reported-by: Olga Kornievskaia <kolga@netapp.com>
+Reviewed-by: Tom Talpey <tom@talpey.com>
+Signed-off-by: Bernard Metzler <bmt@zurich.ibm.com>
+Link: https://lore.kernel.org/r/20221107145057.895747-1-bmt@zurich.ibm.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_cq.c    | 24 ++++++++++++++--
+ drivers/infiniband/sw/siw/siw_verbs.c | 40 ++++++++++++++++++++++++---
+ 2 files changed, 58 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_cq.c b/drivers/infiniband/sw/siw/siw_cq.c
+index d68e37859e73..acc7bcd538b5 100644
+--- a/drivers/infiniband/sw/siw/siw_cq.c
++++ b/drivers/infiniband/sw/siw/siw_cq.c
+@@ -56,8 +56,6 @@ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc)
+       if (READ_ONCE(cqe->flags) & SIW_WQE_VALID) {
+               memset(wc, 0, sizeof(*wc));
+               wc->wr_id = cqe->id;
+-              wc->status = map_cqe_status[cqe->status].ib;
+-              wc->opcode = map_wc_opcode[cqe->opcode];
+               wc->byte_len = cqe->bytes;
+               /*
+@@ -71,10 +69,32 @@ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc)
+                               wc->wc_flags = IB_WC_WITH_INVALIDATE;
+                       }
+                       wc->qp = cqe->base_qp;
++                      wc->opcode = map_wc_opcode[cqe->opcode];
++                      wc->status = map_cqe_status[cqe->status].ib;
+                       siw_dbg_cq(cq,
+                                  "idx %u, type %d, flags %2x, id 0x%pK\n",
+                                  cq->cq_get % cq->num_cqe, cqe->opcode,
+                                  cqe->flags, (void *)(uintptr_t)cqe->id);
++              } else {
++                      /*
++                       * A malicious user may set invalid opcode or
++                       * status in the user mmapped CQE array.
++                       * Sanity check and correct values in that case
++                       * to avoid out-of-bounds access to global arrays
++                       * for opcode and status mapping.
++                       */
++                      u8 opcode = cqe->opcode;
++                      u16 status = cqe->status;
++
++                      if (opcode >= SIW_NUM_OPCODES) {
++                              opcode = 0;
++                              status = IB_WC_GENERAL_ERR;
++                      } else if (status >= SIW_NUM_WC_STATUS) {
++                              status = IB_WC_GENERAL_ERR;
++                      }
++                      wc->opcode = map_wc_opcode[opcode];
++                      wc->status = map_cqe_status[status].ib;
++
+               }
+               WRITE_ONCE(cqe->flags, 0);
+               cq->cq_get++;
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 34e847a91eb8..d043793ff0f5 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -672,13 +672,45 @@ static int siw_copy_inline_sgl(const struct ib_send_wr *core_wr,
+ static int siw_sq_flush_wr(struct siw_qp *qp, const struct ib_send_wr *wr,
+                          const struct ib_send_wr **bad_wr)
+ {
+-      struct siw_sqe sqe = {};
+       int rv = 0;
+       while (wr) {
+-              sqe.id = wr->wr_id;
+-              sqe.opcode = wr->opcode;
+-              rv = siw_sqe_complete(qp, &sqe, 0, SIW_WC_WR_FLUSH_ERR);
++              struct siw_sqe sqe = {};
++
++              switch (wr->opcode) {
++              case IB_WR_RDMA_WRITE:
++                      sqe.opcode = SIW_OP_WRITE;
++                      break;
++              case IB_WR_RDMA_READ:
++                      sqe.opcode = SIW_OP_READ;
++                      break;
++              case IB_WR_RDMA_READ_WITH_INV:
++                      sqe.opcode = SIW_OP_READ_LOCAL_INV;
++                      break;
++              case IB_WR_SEND:
++                      sqe.opcode = SIW_OP_SEND;
++                      break;
++              case IB_WR_SEND_WITH_IMM:
++                      sqe.opcode = SIW_OP_SEND_WITH_IMM;
++                      break;
++              case IB_WR_SEND_WITH_INV:
++                      sqe.opcode = SIW_OP_SEND_REMOTE_INV;
++                      break;
++              case IB_WR_LOCAL_INV:
++                      sqe.opcode = SIW_OP_INVAL_STAG;
++                      break;
++              case IB_WR_REG_MR:
++                      sqe.opcode = SIW_OP_REG_MR;
++                      break;
++              default:
++                      rv = -EINVAL;
++                      break;
++              }
++              if (!rv) {
++                      sqe.id = wr->wr_id;
++                      rv = siw_sqe_complete(qp, &sqe, 0,
++                                            SIW_WC_WR_FLUSH_ERR);
++              }
+               if (rv) {
+                       if (bad_wr)
+                               *bad_wr = wr;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-siw-fix-pointer-cast-warning.patch b/queue-5.10/rdma-siw-fix-pointer-cast-warning.patch
new file mode 100644 (file)
index 0000000..5e11f7c
--- /dev/null
@@ -0,0 +1,47 @@
+From 29929530df7c5092201e668000546433ee3c224b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Dec 2022 18:03:43 +0100
+Subject: RDMA/siw: Fix pointer cast warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 5244ca88671a1981ceec09c5c8809f003e6a62aa ]
+
+The previous build fix left a remaining issue in configurations with
+64-bit dma_addr_t on 32-bit architectures:
+
+drivers/infiniband/sw/siw/siw_qp_tx.c: In function 'siw_get_pblpage':
+drivers/infiniband/sw/siw/siw_qp_tx.c:32:37: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
+   32 |                 return virt_to_page((void *)paddr);
+      |                                     ^
+
+Use the same double cast here that the driver uses elsewhere to convert
+between dma_addr_t and void*.
+
+Fixes: 0d1b756acf60 ("RDMA/siw: Pass a pointer to virt_to_page()")
+Link: https://lore.kernel.org/r/20221215170347.2612403-1-arnd@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Bernard Metzler <bmt@zurich.ibm.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_qp_tx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
+index 3c3ae5ef2942..df8802b4981c 100644
+--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
++++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
+@@ -29,7 +29,7 @@ static struct page *siw_get_pblpage(struct siw_mem *mem, u64 addr, int *idx)
+       dma_addr_t paddr = siw_pbl_get_buffer(pbl, offset, NULL, idx);
+       if (paddr)
+-              return virt_to_page((void *)paddr);
++              return virt_to_page((void *)(uintptr_t)paddr);
+       return NULL;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-siw-set-defined-status-for-work-completion-with.patch b/queue-5.10/rdma-siw-set-defined-status-for-work-completion-with.patch
new file mode 100644 (file)
index 0000000..ff52356
--- /dev/null
@@ -0,0 +1,52 @@
+From 40ef81eb0954657e4df34b5a92365ec2823c2f35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 18:07:47 +0100
+Subject: RDMA/siw: Set defined status for work completion with undefined
+ status
+
+From: Bernard Metzler <bmt@zurich.ibm.com>
+
+[ Upstream commit 60da2d11fcbc043304910e4d2ca82f9bab953e63 ]
+
+A malicious user may write undefined values into memory mapped completion
+queue elements status or opcode. Undefined status or opcode values will
+result in out-of-bounds access to an array mapping siw internal
+representation of opcode and status to RDMA core representation when
+reaping CQ elements. While siw detects those undefined values, it did not
+correctly set completion status to a defined value, thus defeating the
+whole purpose of the check.
+
+This bug leads to the following Smatch static checker warning:
+
+       drivers/infiniband/sw/siw/siw_cq.c:96 siw_reap_cqe()
+       error: buffer overflow 'map_cqe_status' 10 <= 21
+
+Fixes: bdf1da5df9da ("RDMA/siw: Fix immediate work request flush to completion queue")
+Link: https://lore.kernel.org/r/20221115170747.1263298-1-bmt@zurich.ibm.com
+Reported-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Bernard Metzler <bmt@zurich.ibm.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_cq.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_cq.c b/drivers/infiniband/sw/siw/siw_cq.c
+index acc7bcd538b5..403029de6b92 100644
+--- a/drivers/infiniband/sw/siw/siw_cq.c
++++ b/drivers/infiniband/sw/siw/siw_cq.c
+@@ -88,9 +88,9 @@ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc)
+                       if (opcode >= SIW_NUM_OPCODES) {
+                               opcode = 0;
+-                              status = IB_WC_GENERAL_ERR;
++                              status = SIW_WC_GENERAL_ERR;
+                       } else if (status >= SIW_NUM_WC_STATUS) {
+-                              status = IB_WC_GENERAL_ERR;
++                              status = SIW_WC_GENERAL_ERR;
+                       }
+                       wc->opcode = map_wc_opcode[opcode];
+                       wc->status = map_cqe_status[status].ib;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rdma-srp-fix-error-return-code-in-srp_parse_options.patch b/queue-5.10/rdma-srp-fix-error-return-code-in-srp_parse_options.patch
new file mode 100644 (file)
index 0000000..0c6169e
--- /dev/null
@@ -0,0 +1,241 @@
+From c50f0a35f4a265ee91c9339fde26c5685f8a2e37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 12:00:38 +0800
+Subject: RDMA/srp: Fix error return code in srp_parse_options()
+
+From: Wang Yufen <wangyufen@huawei.com>
+
+[ Upstream commit ed461b30b22c8fa85c25189c14cb89f29595cd14 ]
+
+In the previous iteration of the while loop, the "ret" may have been
+assigned a value of 0, so the error return code -EINVAL may have been
+incorrectly set to 0. To fix set valid return code before calling to
+goto. Also investigate each case separately as Andy suggessted.
+
+Fixes: e711f968c49c ("IB/srp: replace custom implementation of hex2bin()")
+Fixes: 2a174df0c602 ("IB/srp: Use kstrtoull() instead of simple_strtoull()")
+Fixes: 19f313438c77 ("IB/srp: Add RDMA/CM support")
+Signed-off-by: Wang Yufen <wangyufen@huawei.com>
+Link: https://lore.kernel.org/r/1669953638-11747-2-git-send-email-wangyufen@huawei.com
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/srp/ib_srp.c | 96 ++++++++++++++++++++++++-----
+ 1 file changed, 82 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index b4ccb333a834..adbd56af379f 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -3397,7 +3397,8 @@ static int srp_parse_options(struct net *net, const char *buf,
+                       break;
+               case SRP_OPT_PKEY:
+-                      if (match_hex(args, &token)) {
++                      ret = match_hex(args, &token);
++                      if (ret) {
+                               pr_warn("bad P_Key parameter '%s'\n", p);
+                               goto out;
+                       }
+@@ -3457,7 +3458,8 @@ static int srp_parse_options(struct net *net, const char *buf,
+                       break;
+               case SRP_OPT_MAX_SECT:
+-                      if (match_int(args, &token)) {
++                      ret = match_int(args, &token);
++                      if (ret) {
+                               pr_warn("bad max sect parameter '%s'\n", p);
+                               goto out;
+                       }
+@@ -3465,8 +3467,15 @@ static int srp_parse_options(struct net *net, const char *buf,
+                       break;
+               case SRP_OPT_QUEUE_SIZE:
+-                      if (match_int(args, &token) || token < 1) {
++                      ret = match_int(args, &token);
++                      if (ret) {
++                              pr_warn("match_int() failed for queue_size parameter '%s', Error %d\n",
++                                      p, ret);
++                              goto out;
++                      }
++                      if (token < 1) {
+                               pr_warn("bad queue_size parameter '%s'\n", p);
++                              ret = -EINVAL;
+                               goto out;
+                       }
+                       target->scsi_host->can_queue = token;
+@@ -3477,25 +3486,40 @@ static int srp_parse_options(struct net *net, const char *buf,
+                       break;
+               case SRP_OPT_MAX_CMD_PER_LUN:
+-                      if (match_int(args, &token) || token < 1) {
++                      ret = match_int(args, &token);
++                      if (ret) {
++                              pr_warn("match_int() failed for max cmd_per_lun parameter '%s', Error %d\n",
++                                      p, ret);
++                              goto out;
++                      }
++                      if (token < 1) {
+                               pr_warn("bad max cmd_per_lun parameter '%s'\n",
+                                       p);
++                              ret = -EINVAL;
+                               goto out;
+                       }
+                       target->scsi_host->cmd_per_lun = token;
+                       break;
+               case SRP_OPT_TARGET_CAN_QUEUE:
+-                      if (match_int(args, &token) || token < 1) {
++                      ret = match_int(args, &token);
++                      if (ret) {
++                              pr_warn("match_int() failed for max target_can_queue parameter '%s', Error %d\n",
++                                      p, ret);
++                              goto out;
++                      }
++                      if (token < 1) {
+                               pr_warn("bad max target_can_queue parameter '%s'\n",
+                                       p);
++                              ret = -EINVAL;
+                               goto out;
+                       }
+                       target->target_can_queue = token;
+                       break;
+               case SRP_OPT_IO_CLASS:
+-                      if (match_hex(args, &token)) {
++                      ret = match_hex(args, &token);
++                      if (ret) {
+                               pr_warn("bad IO class parameter '%s'\n", p);
+                               goto out;
+                       }
+@@ -3504,6 +3528,7 @@ static int srp_parse_options(struct net *net, const char *buf,
+                               pr_warn("unknown IO class parameter value %x specified (use %x or %x).\n",
+                                       token, SRP_REV10_IB_IO_CLASS,
+                                       SRP_REV16A_IB_IO_CLASS);
++                              ret = -EINVAL;
+                               goto out;
+                       }
+                       target->io_class = token;
+@@ -3526,16 +3551,24 @@ static int srp_parse_options(struct net *net, const char *buf,
+                       break;
+               case SRP_OPT_CMD_SG_ENTRIES:
+-                      if (match_int(args, &token) || token < 1 || token > 255) {
++                      ret = match_int(args, &token);
++                      if (ret) {
++                              pr_warn("match_int() failed for max cmd_sg_entries parameter '%s', Error %d\n",
++                                      p, ret);
++                              goto out;
++                      }
++                      if (token < 1 || token > 255) {
+                               pr_warn("bad max cmd_sg_entries parameter '%s'\n",
+                                       p);
++                              ret = -EINVAL;
+                               goto out;
+                       }
+                       target->cmd_sg_cnt = token;
+                       break;
+               case SRP_OPT_ALLOW_EXT_SG:
+-                      if (match_int(args, &token)) {
++                      ret = match_int(args, &token);
++                      if (ret) {
+                               pr_warn("bad allow_ext_sg parameter '%s'\n", p);
+                               goto out;
+                       }
+@@ -3543,43 +3576,77 @@ static int srp_parse_options(struct net *net, const char *buf,
+                       break;
+               case SRP_OPT_SG_TABLESIZE:
+-                      if (match_int(args, &token) || token < 1 ||
+-                                      token > SG_MAX_SEGMENTS) {
++                      ret = match_int(args, &token);
++                      if (ret) {
++                              pr_warn("match_int() failed for max sg_tablesize parameter '%s', Error %d\n",
++                                      p, ret);
++                              goto out;
++                      }
++                      if (token < 1 || token > SG_MAX_SEGMENTS) {
+                               pr_warn("bad max sg_tablesize parameter '%s'\n",
+                                       p);
++                              ret = -EINVAL;
+                               goto out;
+                       }
+                       target->sg_tablesize = token;
+                       break;
+               case SRP_OPT_COMP_VECTOR:
+-                      if (match_int(args, &token) || token < 0) {
++                      ret = match_int(args, &token);
++                      if (ret) {
++                              pr_warn("match_int() failed for comp_vector parameter '%s', Error %d\n",
++                                      p, ret);
++                              goto out;
++                      }
++                      if (token < 0) {
+                               pr_warn("bad comp_vector parameter '%s'\n", p);
++                              ret = -EINVAL;
+                               goto out;
+                       }
+                       target->comp_vector = token;
+                       break;
+               case SRP_OPT_TL_RETRY_COUNT:
+-                      if (match_int(args, &token) || token < 2 || token > 7) {
++                      ret = match_int(args, &token);
++                      if (ret) {
++                              pr_warn("match_int() failed for tl_retry_count parameter '%s', Error %d\n",
++                                      p, ret);
++                              goto out;
++                      }
++                      if (token < 2 || token > 7) {
+                               pr_warn("bad tl_retry_count parameter '%s' (must be a number between 2 and 7)\n",
+                                       p);
++                              ret = -EINVAL;
+                               goto out;
+                       }
+                       target->tl_retry_count = token;
+                       break;
+               case SRP_OPT_MAX_IT_IU_SIZE:
+-                      if (match_int(args, &token) || token < 0) {
++                      ret = match_int(args, &token);
++                      if (ret) {
++                              pr_warn("match_int() failed for max it_iu_size parameter '%s', Error %d\n",
++                                      p, ret);
++                              goto out;
++                      }
++                      if (token < 0) {
+                               pr_warn("bad maximum initiator to target IU size '%s'\n", p);
++                              ret = -EINVAL;
+                               goto out;
+                       }
+                       target->max_it_iu_size = token;
+                       break;
+               case SRP_OPT_CH_COUNT:
+-                      if (match_int(args, &token) || token < 1) {
++                      ret = match_int(args, &token);
++                      if (ret) {
++                              pr_warn("match_int() failed for channel count parameter '%s', Error %d\n",
++                                      p, ret);
++                              goto out;
++                      }
++                      if (token < 1) {
+                               pr_warn("bad channel count %s\n", p);
++                              ret = -EINVAL;
+                               goto out;
+                       }
+                       target->ch_count = token;
+@@ -3588,6 +3655,7 @@ static int srp_parse_options(struct net *net, const char *buf,
+               default:
+                       pr_warn("unknown parameter or missing value '%s' in target creation request\n",
+                               p);
++                      ret = -EINVAL;
+                       goto out;
+               }
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/regulator-core-fix-module-refcount-leak-in-set_suppl.patch b/queue-5.10/regulator-core-fix-module-refcount-leak-in-set_suppl.patch
new file mode 100644 (file)
index 0000000..9db3829
--- /dev/null
@@ -0,0 +1,36 @@
+From 0a640513d0b57a76beb342cde29de9fe8464424b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 20:27:05 +0800
+Subject: regulator: core: fix module refcount leak in set_supply()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit da46ee19cbd8344d6860816b4827a7ce95764867 ]
+
+If create_regulator() fails in set_supply(), the module refcount
+needs be put to keep refcount balanced.
+
+Fixes: e2c09ae7a74d ("regulator: core: Increase refcount for regulator supply's module")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221201122706.4055992-2-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 60c0be2ea5c5..830a9be4432e 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1472,6 +1472,7 @@ static int set_supply(struct regulator_dev *rdev,
+       rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
+       if (rdev->supply == NULL) {
++              module_put(supply_rdev->owner);
+               err = -ENOMEM;
+               return err;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/regulator-core-fix-resource-leak-in-regulator_regist.patch b/queue-5.10/regulator-core-fix-resource-leak-in-regulator_regist.patch
new file mode 100644 (file)
index 0000000..56806a2
--- /dev/null
@@ -0,0 +1,71 @@
+From e320f9cecdcc1748712b800471521ebe64247f2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 10:51:11 +0800
+Subject: regulator: core: fix resource leak in regulator_register()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit ba62319a42c50e6254e98b3f316464fac8e77968 ]
+
+I got some resource leak reports while doing fault injection test:
+
+  OF: ERROR: memory leak, expected refcount 1 instead of 100,
+  of_node_get()/of_node_put() unbalanced - destroy cset entry:
+  attach overlay node /i2c/pmic@64/regulators/buck1
+
+unreferenced object 0xffff88810deea000 (size 512):
+  comm "490-i2c-rt5190a", pid 253, jiffies 4294859840 (age 5061.046s)
+  hex dump (first 32 bytes):
+    00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00  .....N..........
+    ff ff ff ff ff ff ff ff a0 1e 00 a1 ff ff ff ff  ................
+  backtrace:
+    [<00000000d78541e2>] kmalloc_trace+0x21/0x110
+    [<00000000b343d153>] device_private_init+0x32/0xd0
+    [<00000000be1f0c70>] device_add+0xb2d/0x1030
+    [<00000000e3e6344d>] regulator_register+0xaf2/0x12a0
+    [<00000000e2f5e754>] devm_regulator_register+0x57/0xb0
+    [<000000008b898197>] rt5190a_probe+0x52a/0x861 [rt5190a_regulator]
+
+unreferenced object 0xffff88810b617b80 (size 32):
+  comm "490-i2c-rt5190a", pid 253, jiffies 4294859904 (age 5060.983s)
+  hex dump (first 32 bytes):
+    72 65 67 75 6c 61 74 6f 72 2e 32 38 36 38 2d 53  regulator.2868-S
+    55 50 50 4c 59 00 ff ff 29 00 00 00 2b 00 00 00  UPPLY...)...+...
+  backtrace:
+    [<000000009da9280d>] __kmalloc_node_track_caller+0x44/0x1b0
+    [<0000000025c6a4e5>] kstrdup+0x3a/0x70
+    [<00000000790efb69>] create_regulator+0xc0/0x4e0
+    [<0000000005ed203a>] regulator_resolve_supply+0x2d4/0x440
+    [<0000000045796214>] regulator_register+0x10b3/0x12a0
+    [<00000000e2f5e754>] devm_regulator_register+0x57/0xb0
+    [<000000008b898197>] rt5190a_probe+0x52a/0x861 [rt5190a_regulator]
+
+After calling regulator_resolve_supply(), the 'rdev->supply' is set
+by set_supply(), after this set, in the error path, the resources
+need be released, so call regulator_put() to avoid the leaks.
+
+Fixes: aea6cb99703e ("regulator: resolve supply after creating regulator")
+Fixes: 8a866d527ac0 ("regulator: core: Resolve supply name earlier to prevent double-init")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221202025111.496402-1-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 830a9be4432e..4472c31b9b00 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -5400,6 +5400,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
+       regulator_remove_coupling(rdev);
+       mutex_unlock(&regulator_list_mutex);
+ wash:
++      regulator_put(rdev->supply);
+       kfree(rdev->coupling_desc.coupled_rdevs);
+       mutex_lock(&regulator_list_mutex);
+       regulator_ena_gpio_free(rdev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/regulator-core-fix-unbalanced-of-node-refcount-in-re.patch b/queue-5.10/regulator-core-fix-unbalanced-of-node-refcount-in-re.patch
new file mode 100644 (file)
index 0000000..d752399
--- /dev/null
@@ -0,0 +1,43 @@
+From d5d27126ebf4b93731263fbbd832114b40d4c503 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 17:15:08 +0800
+Subject: regulator: core: fix unbalanced of node refcount in
+ regulator_dev_lookup()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit f2b41b748c19962b82709d9f23c6b2b0ce9d2f91 ]
+
+I got the the following report:
+
+  OF: ERROR: memory leak, expected refcount 1 instead of 2,
+  of_node_get()/of_node_put() unbalanced - destroy cset entry:
+  attach overlay node /i2c/pmic@62/regulators/exten
+
+In of_get_regulator(), the node is returned from of_parse_phandle()
+with refcount incremented, after using it, of_node_put() need be called.
+
+Fixes: 69511a452e6d ("regulator: map consumer regulator based on device tree")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221115091508.900752-1-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index eb083b26ab4f..876afa3919c1 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1775,6 +1775,7 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
+               node = of_get_regulator(dev, supply);
+               if (node) {
+                       r = of_find_regulator_by_node(node);
++                      of_node_put(node);
+                       if (r)
+                               return r;
+-- 
+2.35.1
+
diff --git a/queue-5.10/regulator-core-fix-use_count-leakage-when-handling-b.patch b/queue-5.10/regulator-core-fix-use_count-leakage-when-handling-b.patch
new file mode 100644 (file)
index 0000000..9582770
--- /dev/null
@@ -0,0 +1,62 @@
+From 994f0b98f76fcd36665ee53c6dedfc1b28624f98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 11:38:06 +0800
+Subject: regulator: core: fix use_count leakage when handling boot-on
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rui Zhang <zr.zhang@vivo.com>
+
+[ Upstream commit 0591b14ce0398125439c759f889647369aa616a0 ]
+
+I found a use_count leakage towards supply regulator of rdev with
+boot-on option.
+
+┌───────────────────┐           ┌───────────────────┐
+│  regulator_dev A  │           │  regulator_dev B  │
+│     (boot-on)     │           │     (boot-on)     │
+│    use_count=0    │◀──supply──│    use_count=1    │
+│                   │           │                   │
+└───────────────────┘           └───────────────────┘
+
+In case of rdev(A) configured with `regulator-boot-on', the use_count
+of supplying regulator(B) will increment inside
+regulator_enable(rdev->supply).
+
+Thus, B will acts like always-on, and further balanced
+regulator_enable/disable cannot actually disable it anymore.
+
+However, B was also configured with `regulator-boot-on', we wish it
+could be disabled afterwards.
+
+Signed-off-by: Rui Zhang <zr.zhang@vivo.com>
+Link: https://lore.kernel.org/r/20221201033806.2567812-1-zr.zhang@vivo.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 4472c31b9b00..df746ba5c1bc 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1428,7 +1428,13 @@ static int set_machine_constraints(struct regulator_dev *rdev)
+               if (rdev->supply_name && !rdev->supply)
+                       return -EPROBE_DEFER;
+-              if (rdev->supply) {
++              /* If supplying regulator has already been enabled,
++               * it's not intended to have use_count increment
++               * when rdev is only boot-on.
++               */
++              if (rdev->supply &&
++                  (rdev->constraints->always_on ||
++                   !regulator_is_enabled(rdev->supply))) {
+                       ret = regulator_enable(rdev->supply);
+                       if (ret < 0) {
+                               _regulator_put(rdev->supply);
+-- 
+2.35.1
+
diff --git a/queue-5.10/regulator-core-use-kfree_const-to-free-space-conditi.patch b/queue-5.10/regulator-core-use-kfree_const-to-free-space-conditi.patch
new file mode 100644 (file)
index 0000000..80599c1
--- /dev/null
@@ -0,0 +1,38 @@
+From 2d39054a88f43ff73dafca34b08564d31db81028 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 11:46:16 +0800
+Subject: regulator: core: use kfree_const() to free space conditionally
+
+From: Wang ShaoBo <bobo.shaobowang@huawei.com>
+
+[ Upstream commit dc8d006d15b623c1d80b90b45d6dcb6e890dad09 ]
+
+Use kfree_const() to free supply_name conditionally in create_regulator()
+as supply_name may be allocated from kmalloc() or directly from .rodata
+section.
+
+Fixes: 87fe29b61f95 ("regulator: push allocations in create_regulator() outside of lock")
+Signed-off-by: Wang ShaoBo <bobo.shaobowang@huawei.com>
+Link: https://lore.kernel.org/r/20221123034616.3609537-1-bobo.shaobowang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 876afa3919c1..60c0be2ea5c5 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1645,7 +1645,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
+       regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
+       if (regulator == NULL) {
+-              kfree(supply_name);
++              kfree_const(supply_name);
+               return NULL;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/relay-fix-type-mismatch-when-allocating-memory-in-re.patch b/queue-5.10/relay-fix-type-mismatch-when-allocating-memory-in-re.patch
new file mode 100644 (file)
index 0000000..ac7b070
--- /dev/null
@@ -0,0 +1,49 @@
+From 54b5e8d4d2e7277aa6120ef79c04a685d863a195 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 09:23:38 +0000
+Subject: relay: fix type mismatch when allocating memory in relay_create_buf()
+
+From: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+
+[ Upstream commit 4d8586e04602fe42f0a782d2005956f8b6302678 ]
+
+The 'padding' field of the 'rchan_buf' structure is an array of 'size_t'
+elements, but the memory is allocated for an array of 'size_t *' elements.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Link: https://lkml.kernel.org/r/20221129092002.3538384-1-Ilia.Gavrilov@infotecs.ru
+Fixes: b86ff981a825 ("[PATCH] relay: migrate from relayfs to a generic relay API")
+Signed-off-by: Ilia.Gavrilov <Ilia.Gavrilov@infotecs.ru>
+Cc: Colin Ian King <colin.i.king@gmail.com>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: wuchi <wuchi.zero@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/relay.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/relay.c b/kernel/relay.c
+index b08d936d5fa7..067769b80d4a 100644
+--- a/kernel/relay.c
++++ b/kernel/relay.c
+@@ -163,13 +163,13 @@ static struct rchan_buf *relay_create_buf(struct rchan *chan)
+ {
+       struct rchan_buf *buf;
+-      if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t *))
++      if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t))
+               return NULL;
+       buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
+       if (!buf)
+               return NULL;
+-      buf->padding = kmalloc_array(chan->n_subbufs, sizeof(size_t *),
++      buf->padding = kmalloc_array(chan->n_subbufs, sizeof(size_t),
+                                    GFP_KERNEL);
+       if (!buf->padding)
+               goto free_buf;
+-- 
+2.35.1
+
diff --git a/queue-5.10/remoteproc-qcom_q6v5_pas-detach-power-domains-on-rem.patch b/queue-5.10/remoteproc-qcom_q6v5_pas-detach-power-domains-on-rem.patch
new file mode 100644 (file)
index 0000000..dba46d0
--- /dev/null
@@ -0,0 +1,79 @@
+From d41e58e5a7351019568d804b126069fb57114115 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 10:08:16 +0100
+Subject: remoteproc: qcom_q6v5_pas: detach power domains on remove
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit 34d01df00b84127be04c914fc9f8e8be1fcdf851 ]
+
+We need to detach from the power domains also on remove, not just on
+probe fail so a subsequent probe works as expected.
+
+Otherwise the following error appears on re-probe:
+
+[   29.452005] sysfs: cannot create duplicate filename '/devices/genpd:0:3000000.remoteproc'
+[   29.477121] CPU: 1 PID: 483 Comm: sh Tainted: G        W          6.1.0-rc4-00075-g71a113770bda #78
+[   29.510319] Hardware name: Fairphone 4 (DT)
+[   29.538335] Call trace:
+[   29.564470]  dump_backtrace.part.0+0xe0/0xf0
+[   29.592602]  show_stack+0x18/0x30
+[   29.619616]  dump_stack_lvl+0x64/0x80
+[   29.646834]  dump_stack+0x18/0x34
+[   29.673541]  sysfs_warn_dup+0x60/0x7c
+[   29.700592]  sysfs_create_dir_ns+0xec/0x110
+[   29.728057]  kobject_add_internal+0xb8/0x374
+[   29.755530]  kobject_add+0x9c/0x104
+[   29.782072]  device_add+0xbc/0x8a0
+[   29.808445]  device_register+0x20/0x30
+[   29.835175]  genpd_dev_pm_attach_by_id+0xa4/0x190
+[   29.862851]  genpd_dev_pm_attach_by_name+0x3c/0xb0
+[   29.890472]  dev_pm_domain_attach_by_name+0x20/0x30
+[   29.918212]  adsp_probe+0x278/0x580
+[   29.944384]  platform_probe+0x68/0xc0
+[   29.970603]  really_probe+0xbc/0x2dc
+[   29.996662]  __driver_probe_device+0x78/0xe0
+[   30.023491]  device_driver_attach+0x48/0xac
+[   30.050215]  bind_store+0xb8/0x114
+[   30.075957]  drv_attr_store+0x24/0x3c
+[   30.101874]  sysfs_kf_write+0x44/0x54
+[   30.127751]  kernfs_fop_write_iter+0x120/0x1f0
+[   30.154448]  vfs_write+0x1ac/0x380
+[   30.179937]  ksys_write+0x70/0x104
+[   30.205274]  __arm64_sys_write+0x1c/0x2c
+[   30.231060]  invoke_syscall+0x48/0x114
+[   30.256594]  el0_svc_common.constprop.0+0x44/0xec
+[   30.283183]  do_el0_svc+0x2c/0xd0
+[   30.308320]  el0_svc+0x2c/0x84
+[   30.333059]  el0t_64_sync_handler+0xf4/0x120
+[   30.359001]  el0t_64_sync+0x18c/0x190
+[   30.384385] kobject_add_internal failed for genpd:0:3000000.remoteproc with -EEXIST, don't try to register things with the same name in the same directory.
+[   30.406029] remoteproc remoteproc0: releasing 3000000.remoteproc
+[   30.416064] qcom_q6v5_pas: probe of 3000000.remoteproc failed with error -17
+
+Fixes: 17ee2fb4e856 ("remoteproc: qcom: pas: Vote for active/proxy power domains")
+Reviewed-by: Sibi Sankar <quic_sibis@quicinc.com>
+Reviewed-by: Mukesh Ojha <quic_mojha@quicinc.com>
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221118090816.100012-2-luca.weiss@fairphone.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_pas.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index 99b206b00456..d8ef10fba8e8 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -488,6 +488,7 @@ static int adsp_remove(struct platform_device *pdev)
+       qcom_remove_sysmon_subdev(adsp->sysmon);
+       qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
+       qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
++      adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
+       device_init_wakeup(adsp->dev, false);
+       rproc_free(adsp->rproc);
+-- 
+2.35.1
+
diff --git a/queue-5.10/remoteproc-qcom_q6v5_pas-disable-wakeup-on-probe-fai.patch b/queue-5.10/remoteproc-qcom_q6v5_pas-disable-wakeup-on-probe-fai.patch
new file mode 100644 (file)
index 0000000..2a85b4a
--- /dev/null
@@ -0,0 +1,58 @@
+From dd4abcafa080a671df8325021fa6248330b22e3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 10:08:15 +0100
+Subject: remoteproc: qcom_q6v5_pas: disable wakeup on probe fail or remove
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit 9a70551996e699fda262e8d54bbd41739d7aad6d ]
+
+Leaving wakeup enabled during probe fail (-EPROBE_DEFER) or remove makes
+the subsequent probe fail.
+
+[    3.749454] remoteproc remoteproc0: releasing 3000000.remoteproc
+[    3.752949] qcom_q6v5_pas: probe of 3000000.remoteproc failed with error -17
+[    3.878935] remoteproc remoteproc0: releasing 4080000.remoteproc
+[    3.887602] qcom_q6v5_pas: probe of 4080000.remoteproc failed with error -17
+[    4.319552] remoteproc remoteproc0: releasing 8300000.remoteproc
+[    4.332716] qcom_q6v5_pas: probe of 8300000.remoteproc failed with error -17
+
+Fix this by disabling wakeup in both cases so the driver can properly
+probe on the next try.
+
+Fixes: a781e5aa5911 ("remoteproc: core: Prevent system suspend during remoteproc recovery")
+Fixes: dc86c129b4fb ("remoteproc: qcom: pas: Mark devices as wakeup capable")
+Reviewed-by: Mukesh Ojha <quic_mojha@quicinc.com>
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Reviewed-by: Caleb Connolly <caleb.connolly@linaro.org>
+Reviewed-by: Sibi Sankar <quic_sibis@quicinc.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221118090816.100012-1-luca.weiss@fairphone.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_pas.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index 0678b417707e..99b206b00456 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -472,6 +472,7 @@ static int adsp_probe(struct platform_device *pdev)
+ detach_active_pds:
+       adsp_pds_detach(adsp, adsp->active_pds, adsp->active_pd_count);
+ free_rproc:
++      device_init_wakeup(adsp->dev, false);
+       rproc_free(rproc);
+       return ret;
+@@ -487,6 +488,7 @@ static int adsp_remove(struct platform_device *pdev)
+       qcom_remove_sysmon_subdev(adsp->sysmon);
+       qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
+       qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
++      device_init_wakeup(adsp->dev, false);
+       rproc_free(adsp->rproc);
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/remoteproc-qcom_q6v5_pas-fix-missing-of_node_put-in-.patch b/queue-5.10/remoteproc-qcom_q6v5_pas-fix-missing-of_node_put-in-.patch
new file mode 100644 (file)
index 0000000..e7c199c
--- /dev/null
@@ -0,0 +1,37 @@
+From ac44fa1b27ae46f8bfa28630fb9fcc8b6cf152fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Dec 2022 07:06:39 +0000
+Subject: remoteproc: qcom_q6v5_pas: Fix missing of_node_put() in
+ adsp_alloc_memory_region()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 38e7d9c19276832ebb0277f415b9214bf7baeb37 ]
+
+The pointer node is returned by of_parse_phandle() with refcount
+incremented. We should use of_node_put() on it when done.
+
+Fixes: b9e718e950c3 ("remoteproc: Introduce Qualcomm ADSP PIL")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221203070639.15128-1-yuancan@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_pas.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index d8ef10fba8e8..1a0d6eb9425b 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -365,6 +365,7 @@ static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
+       }
+       ret = of_address_to_resource(node, 0, &r);
++      of_node_put(node);
+       if (ret)
+               return ret;
+-- 
+2.35.1
+
diff --git a/queue-5.10/remoteproc-sysmon-fix-memory-leak-in-qcom_add_sysmon.patch b/queue-5.10/remoteproc-sysmon-fix-memory-leak-in-qcom_add_sysmon.patch
new file mode 100644 (file)
index 0000000..b560e58
--- /dev/null
@@ -0,0 +1,48 @@
+From 8ba322fea3cf1477af515246034f2dd6661c4110 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 18:56:50 +0800
+Subject: remoteproc: sysmon: fix memory leak in qcom_add_sysmon_subdev()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit e01ce676aaef3b13d02343d7e70f9637d93a3367 ]
+
+The kfree() should be called when of_irq_get_byname() fails or
+devm_request_threaded_irq() fails in qcom_add_sysmon_subdev(),
+otherwise there will be a memory leak, so add kfree() to fix it.
+
+Fixes: 027045a6e2b7 ("remoteproc: qcom: Add shutdown-ack irq")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221129105650.1539187-1-cuigaosheng1@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_sysmon.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c
+index a26221a6f6c2..c348ea35e47c 100644
+--- a/drivers/remoteproc/qcom_sysmon.c
++++ b/drivers/remoteproc/qcom_sysmon.c
+@@ -625,7 +625,9 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
+               if (sysmon->shutdown_irq != -ENODATA) {
+                       dev_err(sysmon->dev,
+                               "failed to retrieve shutdown-ack IRQ\n");
+-                      return ERR_PTR(sysmon->shutdown_irq);
++                      ret = sysmon->shutdown_irq;
++                      kfree(sysmon);
++                      return ERR_PTR(ret);
+               }
+       } else {
+               ret = devm_request_threaded_irq(sysmon->dev,
+@@ -636,6 +638,7 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
+               if (ret) {
+                       dev_err(sysmon->dev,
+                               "failed to acquire shutdown-ack IRQ\n");
++                      kfree(sysmon);
+                       return ERR_PTR(ret);
+               }
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/riscv-mm-add-arch-hook-arch_clear_hugepage_flags.patch b/queue-5.10/riscv-mm-add-arch-hook-arch_clear_hugepage_flags.patch
new file mode 100644 (file)
index 0000000..aab7d96
--- /dev/null
@@ -0,0 +1,46 @@
+From e421248c544322495e4720d5880a6657a96a6974 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Oct 2022 09:47:25 +0000
+Subject: riscv/mm: add arch hook arch_clear_hugepage_flags
+
+From: Tong Tiangen <tongtiangen@huawei.com>
+
+[ Upstream commit d8bf77a1dc3079692f54be3087a5fd16d90027b0 ]
+
+With the PG_arch_1 we keep track if the page's data cache is clean,
+architecture rely on this property to treat new pages as dirty with
+respect to the data cache and perform the flushing before mapping the pages
+into userspace.
+
+This patch adds a new architecture hook, arch_clear_hugepage_flags,so that
+architectures which rely on the page flags being in a particular state for
+fresh allocations can adjust the flags accordingly when a page is freed
+into the pool.
+
+Fixes: 9e953cda5cdf ("riscv: Introduce huge page support for 32/64bit kernel")
+Signed-off-by: Tong Tiangen <tongtiangen@huawei.com>
+Link: https://lore.kernel.org/r/20221024094725.3054311-3-tongtiangen@huawei.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/hugetlb.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h
+index a5c2ca1d1cd8..ec19d6afc896 100644
+--- a/arch/riscv/include/asm/hugetlb.h
++++ b/arch/riscv/include/asm/hugetlb.h
+@@ -5,4 +5,10 @@
+ #include <asm-generic/hugetlb.h>
+ #include <asm/page.h>
++static inline void arch_clear_hugepage_flags(struct page *page)
++{
++      clear_bit(PG_dcache_clean, &page->flags);
++}
++#define arch_clear_hugepage_flags arch_clear_hugepage_flags
++
+ #endif /* _ASM_RISCV_HUGETLB_H */
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-cmos-call-cmos_wake_setup-from-cmos_do_probe.patch b/queue-5.10/rtc-cmos-call-cmos_wake_setup-from-cmos_do_probe.patch
new file mode 100644 (file)
index 0000000..bbd499d
--- /dev/null
@@ -0,0 +1,147 @@
+From ab6769eadece7425eb39a9c5fe1ab34571e65210 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 13:07:08 +0100
+Subject: rtc: cmos: Call cmos_wake_setup() from cmos_do_probe()
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 508ccdfb86b21da37ad091003a4d4567709d5dfb ]
+
+Notice that cmos_wake_setup() is the only user of acpi_rtc_info and it
+can operate on the cmos_rtc variable directly, so it need not set the
+platform_data pointer before cmos_do_probe() is called.  Instead, it
+can be called by cmos_do_probe() in the case when the platform_data
+pointer is not set to implement the default behavior (which is to use
+the FADT information as long as ACPI support is enabled).
+
+Modify the code accordingly.
+
+While at it, drop a comment that doesn't really match the code it is
+supposed to be describing.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Tested-by: Zhang Rui <rui.zhang@intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/4803444.31r3eYUQgx@kreacher
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Stable-dep-of: 83ebb7b3036d ("rtc: cmos: Disable ACPI RTC event on removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-cmos.c | 47 ++++++++++++++++++++----------------------
+ 1 file changed, 22 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index ff556a93a397..c292af30d4fd 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -750,6 +750,8 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
+               return IRQ_NONE;
+ }
++static void cmos_wake_setup(struct device *dev);
++
+ #ifdef        CONFIG_PNP
+ #define       INITSECTION
+@@ -833,19 +835,27 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
+               if (info->address_space)
+                       address_space = info->address_space;
+-              if (info->rtc_day_alarm && info->rtc_day_alarm < 128)
+-                      cmos_rtc.day_alrm = info->rtc_day_alarm;
+-              if (info->rtc_mon_alarm && info->rtc_mon_alarm < 128)
+-                      cmos_rtc.mon_alrm = info->rtc_mon_alarm;
+-              if (info->rtc_century && info->rtc_century < 128)
+-                      cmos_rtc.century = info->rtc_century;
++              cmos_rtc.day_alrm = info->rtc_day_alarm;
++              cmos_rtc.mon_alrm = info->rtc_mon_alarm;
++              cmos_rtc.century = info->rtc_century;
+               if (info->wake_on && info->wake_off) {
+                       cmos_rtc.wake_on = info->wake_on;
+                       cmos_rtc.wake_off = info->wake_off;
+               }
++      } else {
++              cmos_wake_setup(dev);
+       }
++      if (cmos_rtc.day_alrm >= 128)
++              cmos_rtc.day_alrm = 0;
++
++      if (cmos_rtc.mon_alrm >= 128)
++              cmos_rtc.mon_alrm = 0;
++
++      if (cmos_rtc.century >= 128)
++              cmos_rtc.century = 0;
++
+       cmos_rtc.dev = dev;
+       dev_set_drvdata(dev, &cmos_rtc);
+@@ -1280,13 +1290,6 @@ static void use_acpi_alarm_quirks(void)
+ static inline void use_acpi_alarm_quirks(void) { }
+ #endif
+-/* Every ACPI platform has a mc146818 compatible "cmos rtc".  Here we find
+- * its device node and pass extra config data.  This helps its driver use
+- * capabilities that the now-obsolete mc146818 didn't have, and informs it
+- * that this board's RTC is wakeup-capable (per ACPI spec).
+- */
+-static struct cmos_rtc_board_info acpi_rtc_info;
+-
+ static void cmos_wake_setup(struct device *dev)
+ {
+       if (acpi_disabled)
+@@ -1294,26 +1297,23 @@ static void cmos_wake_setup(struct device *dev)
+       use_acpi_alarm_quirks();
+-      acpi_rtc_info.wake_on = rtc_wake_on;
+-      acpi_rtc_info.wake_off = rtc_wake_off;
++      cmos_rtc.wake_on = rtc_wake_on;
++      cmos_rtc.wake_off = rtc_wake_off;
+-      /* workaround bug in some ACPI tables */
++      /* ACPI tables bug workaround. */
+       if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
+               dev_dbg(dev, "bogus FADT month_alarm (%d)\n",
+                       acpi_gbl_FADT.month_alarm);
+               acpi_gbl_FADT.month_alarm = 0;
+       }
+-      acpi_rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
+-      acpi_rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
+-      acpi_rtc_info.rtc_century = acpi_gbl_FADT.century;
++      cmos_rtc.day_alrm = acpi_gbl_FADT.day_alarm;
++      cmos_rtc.mon_alrm = acpi_gbl_FADT.month_alarm;
++      cmos_rtc.century = acpi_gbl_FADT.century;
+-      /* NOTE:  S4_RTC_WAKE is NOT currently useful to Linux */
+       if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
+               dev_info(dev, "RTC can wake from S4\n");
+-      dev->platform_data = &acpi_rtc_info;
+-
+       /* RTC always wakes from S1/S2/S3, and often S4/STD */
+       device_init_wakeup(dev, 1);
+ }
+@@ -1364,8 +1364,6 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ {
+       int irq, ret;
+-      cmos_wake_setup(&pnp->dev);
+-
+       if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
+               irq = 0;
+ #ifdef CONFIG_X86
+@@ -1473,7 +1471,6 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
+       int irq, ret;
+       cmos_of_init(pdev);
+-      cmos_wake_setup(&pdev->dev);
+       if (RTC_IOMAPPED)
+               resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-cmos-call-rtc_wake_setup-from-cmos_do_probe.patch b/queue-5.10/rtc-cmos-call-rtc_wake_setup-from-cmos_do_probe.patch
new file mode 100644 (file)
index 0000000..64983a8
--- /dev/null
@@ -0,0 +1,103 @@
+From 074e2cff9950fad610308b9c658dd5ae7b1d5662 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 13:09:07 +0100
+Subject: rtc: cmos: Call rtc_wake_setup() from cmos_do_probe()
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 375bbba09692fe4c5218eddee8e312dd733fa846 ]
+
+To reduce code duplication, move the invocation of rtc_wake_setup()
+into cmos_do_probe() and simplify the callers of the latter.
+
+No intentional functional impact.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Tested-by: Zhang Rui <rui.zhang@intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/2143522.irdbgypaU6@kreacher
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Stable-dep-of: 83ebb7b3036d ("rtc: cmos: Disable ACPI RTC event on removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-cmos.c | 28 ++++++++++++----------------
+ 1 file changed, 12 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index c292af30d4fd..445089cad471 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -750,6 +750,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
+               return IRQ_NONE;
+ }
++static inline void rtc_wake_setup(struct device *dev);
+ static void cmos_wake_setup(struct device *dev);
+ #ifdef        CONFIG_PNP
+@@ -943,6 +944,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
+       if (rtc_nvmem_register(cmos_rtc.rtc, &nvmem_cfg))
+               dev_err(dev, "nvmem registration failed\n");
++      /*
++       * Everything has gone well so far, so by default register a handler for
++       * the ACPI RTC fixed event.
++       */
++      if (!info)
++              rtc_wake_setup(dev);
++
+       dev_info(dev, "%s%s, %d bytes nvram%s\n",
+                !is_valid_irq(rtc_irq) ? "no alarms" :
+                cmos_rtc.mon_alrm ? "alarms up to one year" :
+@@ -1362,7 +1370,7 @@ static void rtc_wake_setup(struct device *dev)
+ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ {
+-      int irq, ret;
++      int irq;
+       if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
+               irq = 0;
+@@ -1378,13 +1386,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+               irq = pnp_irq(pnp, 0);
+       }
+-      ret = cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
+-      if (ret)
+-              return ret;
+-
+-      rtc_wake_setup(&pnp->dev);
+-
+-      return 0;
++      return cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
+ }
+ static void cmos_pnp_remove(struct pnp_dev *pnp)
+@@ -1468,7 +1470,7 @@ static inline void cmos_of_init(struct platform_device *pdev) {}
+ static int __init cmos_platform_probe(struct platform_device *pdev)
+ {
+       struct resource *resource;
+-      int irq, ret;
++      int irq;
+       cmos_of_init(pdev);
+@@ -1480,13 +1482,7 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
+       if (irq < 0)
+               irq = -1;
+-      ret = cmos_do_probe(&pdev->dev, resource, irq);
+-      if (ret)
+-              return ret;
+-
+-      rtc_wake_setup(&pdev->dev);
+-
+-      return 0;
++      return cmos_do_probe(&pdev->dev, resource, irq);
+ }
+ static int cmos_platform_remove(struct platform_device *pdev)
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-cmos-disable-acpi-rtc-event-on-removal.patch b/queue-5.10/rtc-cmos-disable-acpi-rtc-event-on-removal.patch
new file mode 100644 (file)
index 0000000..ff9f6f6
--- /dev/null
@@ -0,0 +1,68 @@
+From d3f60b1582a7b109dbe8457feeec4a768c6e1b2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 13:15:36 +0100
+Subject: rtc: cmos: Disable ACPI RTC event on removal
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 83ebb7b3036d151ee39a4a752018665648fc3bd4 ]
+
+Make cmos_do_remove() drop the ACPI RTC fixed event handler so as to
+prevent it from operating on stale data in case the event triggers
+after driver removal.
+
+Fixes: 311ee9c151ad ("rtc: cmos: allow using ACPI for RTC alarm instead of HPET")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Tested-by: Zhang Rui <rui.zhang@intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/2224609.iZASKD2KPV@kreacher
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-cmos.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index dd05c12dada8..7f560937bf7c 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -804,6 +804,14 @@ static void acpi_rtc_event_setup(struct device *dev)
+       acpi_disable_event(ACPI_EVENT_RTC, 0);
+ }
++static void acpi_rtc_event_cleanup(void)
++{
++      if (acpi_disabled)
++              return;
++
++      acpi_remove_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler);
++}
++
+ static void rtc_wake_on(struct device *dev)
+ {
+       acpi_clear_event(ACPI_EVENT_RTC);
+@@ -890,6 +898,10 @@ static inline void acpi_rtc_event_setup(struct device *dev)
+ {
+ }
++static inline void acpi_rtc_event_cleanup(void)
++{
++}
++
+ static inline void acpi_cmos_wake_setup(struct device *dev)
+ {
+ }
+@@ -1143,6 +1155,9 @@ static void cmos_do_remove(struct device *dev)
+                       hpet_unregister_irq_handler(cmos_interrupt);
+       }
++      if (!dev_get_platdata(dev))
++              acpi_rtc_event_cleanup();
++
+       cmos->rtc = NULL;
+       ports = cmos->iomem;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-cmos-eliminate-forward-declarations-of-some-func.patch b/queue-5.10/rtc-cmos-eliminate-forward-declarations-of-some-func.patch
new file mode 100644 (file)
index 0000000..32d9ea6
--- /dev/null
@@ -0,0 +1,362 @@
+From 412f0bdbbdc79aa378e75ceef390ce7154d56941 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 13:09:32 +0100
+Subject: rtc: cmos: Eliminate forward declarations of some functions
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit dca4d3b71c8a09a16951add656711fbd6f5bfbb0 ]
+
+Reorder the ACPI-related code before cmos_do_probe() so as to eliminate
+excessive forward declarations of some functions.
+
+While at it, for consistency, add the inline modifier to the
+definitions of empty stub static funtions and remove it from the
+corresponding definitions of functions with non-empty bodies.
+
+No intentional functional impact.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Tested-by: Zhang Rui <rui.zhang@intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/13157911.uLZWGnKmhe@kreacher
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Stable-dep-of: 83ebb7b3036d ("rtc: cmos: Disable ACPI RTC event on removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-cmos.c | 304 ++++++++++++++++++++---------------------
+ 1 file changed, 149 insertions(+), 155 deletions(-)
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index 445089cad471..541cdae587eb 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -750,8 +750,155 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
+               return IRQ_NONE;
+ }
+-static inline void rtc_wake_setup(struct device *dev);
+-static void cmos_wake_setup(struct device *dev);
++#ifdef        CONFIG_ACPI
++
++#include <linux/acpi.h>
++
++static u32 rtc_handler(void *context)
++{
++      struct device *dev = context;
++      struct cmos_rtc *cmos = dev_get_drvdata(dev);
++      unsigned char rtc_control = 0;
++      unsigned char rtc_intr;
++      unsigned long flags;
++
++
++      /*
++       * Always update rtc irq when ACPI is used as RTC Alarm.
++       * Or else, ACPI SCI is enabled during suspend/resume only,
++       * update rtc irq in that case.
++       */
++      if (cmos_use_acpi_alarm())
++              cmos_interrupt(0, (void *)cmos->rtc);
++      else {
++              /* Fix me: can we use cmos_interrupt() here as well? */
++              spin_lock_irqsave(&rtc_lock, flags);
++              if (cmos_rtc.suspend_ctrl)
++                      rtc_control = CMOS_READ(RTC_CONTROL);
++              if (rtc_control & RTC_AIE) {
++                      cmos_rtc.suspend_ctrl &= ~RTC_AIE;
++                      CMOS_WRITE(rtc_control, RTC_CONTROL);
++                      rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
++                      rtc_update_irq(cmos->rtc, 1, rtc_intr);
++              }
++              spin_unlock_irqrestore(&rtc_lock, flags);
++      }
++
++      pm_wakeup_hard_event(dev);
++      acpi_clear_event(ACPI_EVENT_RTC);
++      acpi_disable_event(ACPI_EVENT_RTC, 0);
++      return ACPI_INTERRUPT_HANDLED;
++}
++
++static void rtc_wake_setup(struct device *dev)
++{
++      if (acpi_disabled)
++              return;
++
++      acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
++      /*
++       * After the RTC handler is installed, the Fixed_RTC event should
++       * be disabled. Only when the RTC alarm is set will it be enabled.
++       */
++      acpi_clear_event(ACPI_EVENT_RTC);
++      acpi_disable_event(ACPI_EVENT_RTC, 0);
++}
++
++static void rtc_wake_on(struct device *dev)
++{
++      acpi_clear_event(ACPI_EVENT_RTC);
++      acpi_enable_event(ACPI_EVENT_RTC, 0);
++}
++
++static void rtc_wake_off(struct device *dev)
++{
++      acpi_disable_event(ACPI_EVENT_RTC, 0);
++}
++
++#ifdef CONFIG_X86
++/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
++static void use_acpi_alarm_quirks(void)
++{
++      if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
++              return;
++
++      if (!is_hpet_enabled())
++              return;
++
++      if (dmi_get_bios_year() < 2015)
++              return;
++
++      use_acpi_alarm = true;
++}
++#else
++static inline void use_acpi_alarm_quirks(void) { }
++#endif
++
++static void cmos_wake_setup(struct device *dev)
++{
++      if (acpi_disabled)
++              return;
++
++      use_acpi_alarm_quirks();
++
++      cmos_rtc.wake_on = rtc_wake_on;
++      cmos_rtc.wake_off = rtc_wake_off;
++
++      /* ACPI tables bug workaround. */
++      if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
++              dev_dbg(dev, "bogus FADT month_alarm (%d)\n",
++                      acpi_gbl_FADT.month_alarm);
++              acpi_gbl_FADT.month_alarm = 0;
++      }
++
++      cmos_rtc.day_alrm = acpi_gbl_FADT.day_alarm;
++      cmos_rtc.mon_alrm = acpi_gbl_FADT.month_alarm;
++      cmos_rtc.century = acpi_gbl_FADT.century;
++
++      if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
++              dev_info(dev, "RTC can wake from S4\n");
++
++      /* RTC always wakes from S1/S2/S3, and often S4/STD */
++      device_init_wakeup(dev, 1);
++}
++
++static void cmos_check_acpi_rtc_status(struct device *dev,
++                                            unsigned char *rtc_control)
++{
++      struct cmos_rtc *cmos = dev_get_drvdata(dev);
++      acpi_event_status rtc_status;
++      acpi_status status;
++
++      if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC)
++              return;
++
++      status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status);
++      if (ACPI_FAILURE(status)) {
++              dev_err(dev, "Could not get RTC status\n");
++      } else if (rtc_status & ACPI_EVENT_FLAG_SET) {
++              unsigned char mask;
++              *rtc_control &= ~RTC_AIE;
++              CMOS_WRITE(*rtc_control, RTC_CONTROL);
++              mask = CMOS_READ(RTC_INTR_FLAGS);
++              rtc_update_irq(cmos->rtc, 1, mask);
++      }
++}
++
++#else /* !CONFIG_ACPI */
++
++static inline void rtc_wake_setup(struct device *dev)
++{
++}
++
++static inline void cmos_wake_setup(struct device *dev)
++{
++}
++
++static inline void cmos_check_acpi_rtc_status(struct device *dev,
++                                            unsigned char *rtc_control)
++{
++}
++#endif /* CONFIG_ACPI */
+ #ifdef        CONFIG_PNP
+ #define       INITSECTION
+@@ -1145,9 +1292,6 @@ static void cmos_check_wkalrm(struct device *dev)
+       }
+ }
+-static void cmos_check_acpi_rtc_status(struct device *dev,
+-                                     unsigned char *rtc_control);
+-
+ static int __maybe_unused cmos_resume(struct device *dev)
+ {
+       struct cmos_rtc *cmos = dev_get_drvdata(dev);
+@@ -1214,156 +1358,6 @@ static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume);
+  * predate even PNPBIOS should set up platform_bus devices.
+  */
+-#ifdef        CONFIG_ACPI
+-
+-#include <linux/acpi.h>
+-
+-static u32 rtc_handler(void *context)
+-{
+-      struct device *dev = context;
+-      struct cmos_rtc *cmos = dev_get_drvdata(dev);
+-      unsigned char rtc_control = 0;
+-      unsigned char rtc_intr;
+-      unsigned long flags;
+-
+-
+-      /*
+-       * Always update rtc irq when ACPI is used as RTC Alarm.
+-       * Or else, ACPI SCI is enabled during suspend/resume only,
+-       * update rtc irq in that case.
+-       */
+-      if (cmos_use_acpi_alarm())
+-              cmos_interrupt(0, (void *)cmos->rtc);
+-      else {
+-              /* Fix me: can we use cmos_interrupt() here as well? */
+-              spin_lock_irqsave(&rtc_lock, flags);
+-              if (cmos_rtc.suspend_ctrl)
+-                      rtc_control = CMOS_READ(RTC_CONTROL);
+-              if (rtc_control & RTC_AIE) {
+-                      cmos_rtc.suspend_ctrl &= ~RTC_AIE;
+-                      CMOS_WRITE(rtc_control, RTC_CONTROL);
+-                      rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
+-                      rtc_update_irq(cmos->rtc, 1, rtc_intr);
+-              }
+-              spin_unlock_irqrestore(&rtc_lock, flags);
+-      }
+-
+-      pm_wakeup_hard_event(dev);
+-      acpi_clear_event(ACPI_EVENT_RTC);
+-      acpi_disable_event(ACPI_EVENT_RTC, 0);
+-      return ACPI_INTERRUPT_HANDLED;
+-}
+-
+-static inline void rtc_wake_setup(struct device *dev)
+-{
+-      if (acpi_disabled)
+-              return;
+-
+-      acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
+-      /*
+-       * After the RTC handler is installed, the Fixed_RTC event should
+-       * be disabled. Only when the RTC alarm is set will it be enabled.
+-       */
+-      acpi_clear_event(ACPI_EVENT_RTC);
+-      acpi_disable_event(ACPI_EVENT_RTC, 0);
+-}
+-
+-static void rtc_wake_on(struct device *dev)
+-{
+-      acpi_clear_event(ACPI_EVENT_RTC);
+-      acpi_enable_event(ACPI_EVENT_RTC, 0);
+-}
+-
+-static void rtc_wake_off(struct device *dev)
+-{
+-      acpi_disable_event(ACPI_EVENT_RTC, 0);
+-}
+-
+-#ifdef CONFIG_X86
+-/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
+-static void use_acpi_alarm_quirks(void)
+-{
+-      if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+-              return;
+-
+-      if (!is_hpet_enabled())
+-              return;
+-
+-      if (dmi_get_bios_year() < 2015)
+-              return;
+-
+-      use_acpi_alarm = true;
+-}
+-#else
+-static inline void use_acpi_alarm_quirks(void) { }
+-#endif
+-
+-static void cmos_wake_setup(struct device *dev)
+-{
+-      if (acpi_disabled)
+-              return;
+-
+-      use_acpi_alarm_quirks();
+-
+-      cmos_rtc.wake_on = rtc_wake_on;
+-      cmos_rtc.wake_off = rtc_wake_off;
+-
+-      /* ACPI tables bug workaround. */
+-      if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
+-              dev_dbg(dev, "bogus FADT month_alarm (%d)\n",
+-                      acpi_gbl_FADT.month_alarm);
+-              acpi_gbl_FADT.month_alarm = 0;
+-      }
+-
+-      cmos_rtc.day_alrm = acpi_gbl_FADT.day_alarm;
+-      cmos_rtc.mon_alrm = acpi_gbl_FADT.month_alarm;
+-      cmos_rtc.century = acpi_gbl_FADT.century;
+-
+-      if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
+-              dev_info(dev, "RTC can wake from S4\n");
+-
+-      /* RTC always wakes from S1/S2/S3, and often S4/STD */
+-      device_init_wakeup(dev, 1);
+-}
+-
+-static void cmos_check_acpi_rtc_status(struct device *dev,
+-                                     unsigned char *rtc_control)
+-{
+-      struct cmos_rtc *cmos = dev_get_drvdata(dev);
+-      acpi_event_status rtc_status;
+-      acpi_status status;
+-
+-      if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC)
+-              return;
+-
+-      status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status);
+-      if (ACPI_FAILURE(status)) {
+-              dev_err(dev, "Could not get RTC status\n");
+-      } else if (rtc_status & ACPI_EVENT_FLAG_SET) {
+-              unsigned char mask;
+-              *rtc_control &= ~RTC_AIE;
+-              CMOS_WRITE(*rtc_control, RTC_CONTROL);
+-              mask = CMOS_READ(RTC_INTR_FLAGS);
+-              rtc_update_irq(cmos->rtc, 1, mask);
+-      }
+-}
+-
+-#else
+-
+-static void cmos_wake_setup(struct device *dev)
+-{
+-}
+-
+-static void cmos_check_acpi_rtc_status(struct device *dev,
+-                                     unsigned char *rtc_control)
+-{
+-}
+-
+-static void rtc_wake_setup(struct device *dev)
+-{
+-}
+-#endif
+-
+ #ifdef        CONFIG_PNP
+ #include <linux/pnp.h>
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-cmos-fix-build-on-non-acpi-platforms.patch b/queue-5.10/rtc-cmos-fix-build-on-non-acpi-platforms.patch
new file mode 100644 (file)
index 0000000..8e33c82
--- /dev/null
@@ -0,0 +1,38 @@
+From 14360235807edb54bf3983294df62a0715734ac4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 22:35:11 +0200
+Subject: rtc: cmos: fix build on non-ACPI platforms
+
+From: Alexandre Belloni <alexandre.belloni@bootlin.com>
+
+[ Upstream commit db4e955ae333567dea02822624106c0b96a2f84f ]
+
+Now that rtc_wake_setup is called outside of cmos_wake_setup, it also need
+to be defined on non-ACPI platforms.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Link: https://lore.kernel.org/r/20221018203512.2532407-1-alexandre.belloni@bootlin.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Stable-dep-of: 83ebb7b3036d ("rtc: cmos: Disable ACPI RTC event on removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-cmos.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index 426e6a67cc38..ff556a93a397 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -1351,6 +1351,9 @@ static void cmos_check_acpi_rtc_status(struct device *dev,
+ {
+ }
++static void rtc_wake_setup(struct device *dev)
++{
++}
+ #endif
+ #ifdef        CONFIG_PNP
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-cmos-fix-event-handler-registration-ordering-iss.patch b/queue-5.10/rtc-cmos-fix-event-handler-registration-ordering-iss.patch
new file mode 100644 (file)
index 0000000..c347232
--- /dev/null
@@ -0,0 +1,124 @@
+From 8fb4bd51a82e78a87b9037af94a1ce1039100bd8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Oct 2022 20:07:01 +0200
+Subject: rtc: cmos: Fix event handler registration ordering issue
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 4919d3eb2ec0ee364f7e3cf2d99646c1b224fae8 ]
+
+Because acpi_install_fixed_event_handler() enables the event
+automatically on success, it is incorrect to call it before the
+handler routine passed to it is ready to handle events.
+
+Unfortunately, the rtc-cmos driver does exactly the incorrect thing
+by calling cmos_wake_setup(), which passes rtc_handler() to
+acpi_install_fixed_event_handler(), before cmos_do_probe(), because
+rtc_handler() uses dev_get_drvdata() to get to the cmos object
+pointer and the driver data pointer is only populated in
+cmos_do_probe().
+
+This leads to a NULL pointer dereference in rtc_handler() on boot
+if the RTC fixed event happens to be active at the init time.
+
+To address this issue, change the initialization ordering of the
+driver so that cmos_wake_setup() is always called after a successful
+cmos_do_probe() call.
+
+While at it, change cmos_pnp_probe() to call cmos_do_probe() after
+the initial if () statement used for computing the IRQ argument to
+be passed to cmos_do_probe() which is cleaner than calling it in
+each branch of that if () (local variable "irq" can be of type int,
+because it is passed to that function as an argument of type int).
+
+Note that commit 6492fed7d8c9 ("rtc: rtc-cmos: Do not check
+ACPI_FADT_LOW_POWER_S0") caused this issue to affect a larger number
+of systems, because previously it only affected systems with
+ACPI_FADT_LOW_POWER_S0 set, but it is present regardless of that
+commit.
+
+Fixes: 6492fed7d8c9 ("rtc: rtc-cmos: Do not check ACPI_FADT_LOW_POWER_S0")
+Fixes: a474aaedac99 ("rtc-cmos: move wake setup from ACPI glue into RTC driver")
+Link: https://lore.kernel.org/linux-acpi/20221010141630.zfzi7mk7zvnmclzy@techsingularity.net/
+Reported-by: Mel Gorman <mgorman@techsingularity.net>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Mel Gorman <mgorman@techsingularity.net>
+Link: https://lore.kernel.org/r/5629262.DvuYhMxLoT@kreacher
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Stable-dep-of: 83ebb7b3036d ("rtc: cmos: Disable ACPI RTC event on removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-cmos.c | 29 +++++++++++++++++++----------
+ 1 file changed, 19 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index 19bc1d8a5de5..449818732acf 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -1357,10 +1357,10 @@ static void cmos_check_acpi_rtc_status(struct device *dev,
+ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ {
+-      cmos_wake_setup(&pnp->dev);
++      int irq, ret;
+       if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
+-              unsigned int irq = 0;
++              irq = 0;
+ #ifdef CONFIG_X86
+               /* Some machines contain a PNP entry for the RTC, but
+                * don't define the IRQ. It should always be safe to
+@@ -1369,13 +1369,17 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+               if (nr_legacy_irqs())
+                       irq = RTC_IRQ;
+ #endif
+-              return cmos_do_probe(&pnp->dev,
+-                              pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
+       } else {
+-              return cmos_do_probe(&pnp->dev,
+-                              pnp_get_resource(pnp, IORESOURCE_IO, 0),
+-                              pnp_irq(pnp, 0));
++              irq = pnp_irq(pnp, 0);
+       }
++
++      ret = cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
++      if (ret)
++              return ret;
++
++      cmos_wake_setup(&pnp->dev);
++
++      return 0;
+ }
+ static void cmos_pnp_remove(struct pnp_dev *pnp)
+@@ -1459,10 +1463,9 @@ static inline void cmos_of_init(struct platform_device *pdev) {}
+ static int __init cmos_platform_probe(struct platform_device *pdev)
+ {
+       struct resource *resource;
+-      int irq;
++      int irq, ret;
+       cmos_of_init(pdev);
+-      cmos_wake_setup(&pdev->dev);
+       if (RTC_IOMAPPED)
+               resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
+@@ -1472,7 +1475,13 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
+       if (irq < 0)
+               irq = -1;
+-      return cmos_do_probe(&pdev->dev, resource, irq);
++      ret = cmos_do_probe(&pdev->dev, resource, irq);
++      if (ret)
++              return ret;
++
++      cmos_wake_setup(&pdev->dev);
++
++      return 0;
+ }
+ static int cmos_platform_remove(struct platform_device *pdev)
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-cmos-fix-wake-alarm-breakage.patch b/queue-5.10/rtc-cmos-fix-wake-alarm-breakage.patch
new file mode 100644 (file)
index 0000000..70d3c5a
--- /dev/null
@@ -0,0 +1,92 @@
+From f75b60fc7f86039f9627a2e5e1406de278edf37e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 18:09:31 +0200
+Subject: rtc: cmos: Fix wake alarm breakage
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 0782b66ed2fbb035dda76111df0954515e417b24 ]
+
+Commit 4919d3eb2ec0 ("rtc: cmos: Fix event handler registration
+ordering issue") overlooked the fact that cmos_do_probe() depended
+on the preparations carried out by cmos_wake_setup() and the wake
+alarm stopped working after the ordering of them had been changed.
+
+Address this by partially reverting commit 4919d3eb2ec0 so that
+cmos_wake_setup() is called before cmos_do_probe() again and moving
+the rtc_wake_setup() invocation from cmos_wake_setup() directly to the
+callers of cmos_do_probe() where it will happen after a successful
+completion of the latter.
+
+Fixes: 4919d3eb2ec0 ("rtc: cmos: Fix event handler registration ordering issue")
+Reported-by: Zhang Rui <rui.zhang@intel.com>
+Reported-by: Todd Brandt <todd.e.brandt@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://lore.kernel.org/r/5887691.lOV4Wx5bFT@kreacher
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Stable-dep-of: 83ebb7b3036d ("rtc: cmos: Disable ACPI RTC event on removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-cmos.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index 449818732acf..426e6a67cc38 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -1238,6 +1238,9 @@ static u32 rtc_handler(void *context)
+ static inline void rtc_wake_setup(struct device *dev)
+ {
++      if (acpi_disabled)
++              return;
++
+       acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
+       /*
+        * After the RTC handler is installed, the Fixed_RTC event should
+@@ -1291,7 +1294,6 @@ static void cmos_wake_setup(struct device *dev)
+       use_acpi_alarm_quirks();
+-      rtc_wake_setup(dev);
+       acpi_rtc_info.wake_on = rtc_wake_on;
+       acpi_rtc_info.wake_off = rtc_wake_off;
+@@ -1359,6 +1361,8 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ {
+       int irq, ret;
++      cmos_wake_setup(&pnp->dev);
++
+       if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
+               irq = 0;
+ #ifdef CONFIG_X86
+@@ -1377,7 +1381,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+       if (ret)
+               return ret;
+-      cmos_wake_setup(&pnp->dev);
++      rtc_wake_setup(&pnp->dev);
+       return 0;
+ }
+@@ -1466,6 +1470,7 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
+       int irq, ret;
+       cmos_of_init(pdev);
++      cmos_wake_setup(&pdev->dev);
+       if (RTC_IOMAPPED)
+               resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
+@@ -1479,7 +1484,7 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
+       if (ret)
+               return ret;
+-      cmos_wake_setup(&pdev->dev);
++      rtc_wake_setup(&pdev->dev);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-cmos-rename-acpi-related-functions.patch b/queue-5.10/rtc-cmos-rename-acpi-related-functions.patch
new file mode 100644 (file)
index 0000000..cede29d
--- /dev/null
@@ -0,0 +1,87 @@
+From 0afe9f729e0794cd7c85016e4091010222b6e049 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 13:12:00 +0100
+Subject: rtc: cmos: Rename ACPI-related functions
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit d13e9ad9f5146f066a5c5a1cc993d09e4fb21ead ]
+
+The names of rtc_wake_setup() and cmos_wake_setup() don't indicate
+that these functions are ACPI-related, which is the case, and the
+former doesn't really reflect the role of the function.
+
+Rename them to acpi_rtc_event_setup() and acpi_cmos_wake_setup(),
+respectively, to address this shortcoming.
+
+No intentional functional impact.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Tested-by: Zhang Rui <rui.zhang@intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/3225614.44csPzL39Z@kreacher
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Stable-dep-of: 83ebb7b3036d ("rtc: cmos: Disable ACPI RTC event on removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-cmos.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index 541cdae587eb..dd05c12dada8 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -790,7 +790,7 @@ static u32 rtc_handler(void *context)
+       return ACPI_INTERRUPT_HANDLED;
+ }
+-static void rtc_wake_setup(struct device *dev)
++static void acpi_rtc_event_setup(struct device *dev)
+ {
+       if (acpi_disabled)
+               return;
+@@ -834,7 +834,7 @@ static void use_acpi_alarm_quirks(void)
+ static inline void use_acpi_alarm_quirks(void) { }
+ #endif
+-static void cmos_wake_setup(struct device *dev)
++static void acpi_cmos_wake_setup(struct device *dev)
+ {
+       if (acpi_disabled)
+               return;
+@@ -886,11 +886,11 @@ static void cmos_check_acpi_rtc_status(struct device *dev,
+ #else /* !CONFIG_ACPI */
+-static inline void rtc_wake_setup(struct device *dev)
++static inline void acpi_rtc_event_setup(struct device *dev)
+ {
+ }
+-static inline void cmos_wake_setup(struct device *dev)
++static inline void acpi_cmos_wake_setup(struct device *dev)
+ {
+ }
+@@ -992,7 +992,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
+                       cmos_rtc.wake_off = info->wake_off;
+               }
+       } else {
+-              cmos_wake_setup(dev);
++              acpi_cmos_wake_setup(dev);
+       }
+       if (cmos_rtc.day_alrm >= 128)
+@@ -1096,7 +1096,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
+        * the ACPI RTC fixed event.
+        */
+       if (!info)
+-              rtc_wake_setup(dev);
++              acpi_rtc_event_setup(dev);
+       dev_info(dev, "%s%s, %d bytes nvram%s\n",
+                !is_valid_irq(rtc_irq) ? "no alarms" :
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-mxc_v2-add-missing-clk_disable_unprepare.patch b/queue-5.10/rtc-mxc_v2-add-missing-clk_disable_unprepare.patch
new file mode 100644 (file)
index 0000000..9d375b4
--- /dev/null
@@ -0,0 +1,40 @@
+From c3fff7803679dd98736d765c2f43623527663e4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 16:50:46 +0800
+Subject: rtc: mxc_v2: Add missing clk_disable_unprepare()
+
+From: GUO Zihua <guozihua@huawei.com>
+
+[ Upstream commit 55d5a86618d3b1a768bce01882b74cbbd2651975 ]
+
+The call to clk_disable_unprepare() is left out in the error handling of
+devm_rtc_allocate_device. Add it back.
+
+Fixes: 5490a1e018a4 ("rtc: mxc_v2: fix possible race condition")
+Signed-off-by: GUO Zihua <guozihua@huawei.com>
+Link: https://lore.kernel.org/r/20221122085046.21689-1-guozihua@huawei.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-mxc_v2.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c
+index d349cef09cb7..48595b00ebb3 100644
+--- a/drivers/rtc/rtc-mxc_v2.c
++++ b/drivers/rtc/rtc-mxc_v2.c
+@@ -337,8 +337,10 @@ static int mxc_rtc_probe(struct platform_device *pdev)
+       }
+       pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
+-      if (IS_ERR(pdata->rtc))
++      if (IS_ERR(pdata->rtc)) {
++              clk_disable_unprepare(pdata->clk);
+               return PTR_ERR(pdata->rtc);
++      }
+       pdata->rtc->ops = &mxc_rtc_ops;
+       pdata->rtc->range_max = U32_MAX;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-pcf85063-fix-pcf85063_clkout_control.patch b/queue-5.10/rtc-pcf85063-fix-pcf85063_clkout_control.patch
new file mode 100644 (file)
index 0000000..5816078
--- /dev/null
@@ -0,0 +1,37 @@
+From 6095e6536a1291e45cfd9f0779f038cb3e3b2b66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Dec 2022 23:35:53 +0100
+Subject: rtc: pcf85063: fix pcf85063_clkout_control
+
+From: Alexandre Belloni <alexandre.belloni@bootlin.com>
+
+[ Upstream commit c2d12e85336f6d4172fb2bab5935027c446d7343 ]
+
+pcf85063_clkout_control reads the wrong register but then update the
+correct one.
+
+Reported-by: Janne Terho <janne.terho@ouman.fi>
+Fixes: 8c229ab6048b ("rtc: pcf85063: Add pcf85063 clkout control to common clock framework")
+Link: https://lore.kernel.org/r/20221211223553.59955-1-alexandre.belloni@bootlin.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-pcf85063.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
+index d739b0c965aa..449204d84c61 100644
+--- a/drivers/rtc/rtc-pcf85063.c
++++ b/drivers/rtc/rtc-pcf85063.c
+@@ -430,7 +430,7 @@ static int pcf85063_clkout_control(struct clk_hw *hw, bool enable)
+       unsigned int buf;
+       int ret;
+-      ret = regmap_read(pcf85063->regmap, PCF85063_REG_OFFSET, &buf);
++      ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &buf);
+       if (ret < 0)
+               return ret;
+       buf &= PCF85063_REG_CLKO_F_MASK;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-pcf85063-fix-reading-alarm.patch b/queue-5.10/rtc-pcf85063-fix-reading-alarm.patch
new file mode 100644 (file)
index 0000000..1c39354
--- /dev/null
@@ -0,0 +1,46 @@
+From ca08b300acfa82682c2e23c2772f899e00dd35d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Sep 2022 09:41:41 +0200
+Subject: rtc: pcf85063: Fix reading alarm
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit a6ceee26fd5ed9b5bd37322b1ca88e4548cee4a3 ]
+
+If the alarms are disabled the topmost bit (AEN_*) is set in the alarm
+registers. This is also interpreted in BCD number leading to this warning:
+rtc rtc0: invalid alarm value: 2022-09-21T80:80:80
+
+Fix this by masking alarm enabling and reserved bits.
+
+Fixes: 05cb3a56ee8c ("rtc: pcf85063: add alarm support")
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Link: https://lore.kernel.org/r/20220921074141.3903104-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-pcf85063.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
+index 62684ca3a665..d739b0c965aa 100644
+--- a/drivers/rtc/rtc-pcf85063.c
++++ b/drivers/rtc/rtc-pcf85063.c
+@@ -167,10 +167,10 @@ static int pcf85063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+       if (ret)
+               return ret;
+-      alrm->time.tm_sec = bcd2bin(buf[0]);
+-      alrm->time.tm_min = bcd2bin(buf[1]);
+-      alrm->time.tm_hour = bcd2bin(buf[2]);
+-      alrm->time.tm_mday = bcd2bin(buf[3]);
++      alrm->time.tm_sec = bcd2bin(buf[0] & 0x7f);
++      alrm->time.tm_min = bcd2bin(buf[1] & 0x7f);
++      alrm->time.tm_hour = bcd2bin(buf[2] & 0x3f);
++      alrm->time.tm_mday = bcd2bin(buf[3] & 0x3f);
+       ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &val);
+       if (ret)
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-pic32-move-devm_rtc_allocate_device-earlier-in-p.patch b/queue-5.10/rtc-pic32-move-devm_rtc_allocate_device-earlier-in-p.patch
new file mode 100644 (file)
index 0000000..7d8fcd0
--- /dev/null
@@ -0,0 +1,52 @@
+From 0156938b4392feaa0829eba786a90b2bd84f1f02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 09:59:53 +0800
+Subject: rtc: pic32: Move devm_rtc_allocate_device earlier in
+ pic32_rtc_probe()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 90cd5c88830140c9fade92a8027e0fb2c6e4cc49 ]
+
+The pic32_rtc_enable(pdata, 0) and clk_disable_unprepare(pdata->clk)
+should be called in the error handling of devm_rtc_allocate_device(),
+so we should move devm_rtc_allocate_device earlier in pic32_rtc_probe()
+to fix it.
+
+Fixes: 6515e23b9fde ("rtc: pic32: convert to devm_rtc_allocate_device")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Link: https://lore.kernel.org/r/20221123015953.1998521-1-cuigaosheng1@huawei.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-pic32.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c
+index 2b6946744654..7be1ca1633fc 100644
+--- a/drivers/rtc/rtc-pic32.c
++++ b/drivers/rtc/rtc-pic32.c
+@@ -324,16 +324,16 @@ static int pic32_rtc_probe(struct platform_device *pdev)
+       spin_lock_init(&pdata->alarm_lock);
++      pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
++      if (IS_ERR(pdata->rtc))
++              return PTR_ERR(pdata->rtc);
++
+       clk_prepare_enable(pdata->clk);
+       pic32_rtc_enable(pdata, 1);
+       device_init_wakeup(&pdev->dev, 1);
+-      pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
+-      if (IS_ERR(pdata->rtc))
+-              return PTR_ERR(pdata->rtc);
+-
+       pdata->rtc->ops = &pic32_rtcops;
+       pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+       pdata->rtc->range_max = RTC_TIMESTAMP_END_2099;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-rtc-cmos-do-not-check-acpi_fadt_low_power_s0.patch b/queue-5.10/rtc-rtc-cmos-do-not-check-acpi_fadt_low_power_s0.patch
new file mode 100644 (file)
index 0000000..13a437a
--- /dev/null
@@ -0,0 +1,58 @@
+From c5d36d39a4187f66b478a088b0ecaba0ea08585d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Aug 2022 20:23:59 +0200
+Subject: rtc: rtc-cmos: Do not check ACPI_FADT_LOW_POWER_S0
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 6492fed7d8c95f53b0b804ef541324d924d95d41 ]
+
+The ACPI_FADT_LOW_POWER_S0 flag merely means that it is better to
+use low-power S0 idle on the given platform than S3 (provided that
+the latter is supported) and it doesn't preclude using either of
+them (which of them will be used depends on the choices made by user
+space).
+
+For this reason, there is no benefit from checking that flag in
+use_acpi_alarm_quirks().
+
+First off, it cannot be a bug to do S3 with use_acpi_alarm set,
+because S3 can be used on systems with ACPI_FADT_LOW_POWER_S0 and it
+must work if really supported, so the ACPI_FADT_LOW_POWER_S0 check is
+not needed to protect the S3-capable systems from failing.
+
+Second, suspend-to-idle can be carried out on a system with
+ACPI_FADT_LOW_POWER_S0 unset and it is expected to work, so if setting
+use_acpi_alarm is needed to handle that case correctly, it should be
+set regardless of the ACPI_FADT_LOW_POWER_S0 value.
+
+Accordingly, drop the ACPI_FADT_LOW_POWER_S0 check from
+use_acpi_alarm_quirks().
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/12054246.O9o76ZdvQC@kreacher
+Stable-dep-of: 83ebb7b3036d ("rtc: cmos: Disable ACPI RTC event on removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-cmos.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index d4f6c4dd42c4..19bc1d8a5de5 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -1265,9 +1265,6 @@ static void use_acpi_alarm_quirks(void)
+       if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+               return;
+-      if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0))
+-              return;
+-
+       if (!is_hpet_enabled())
+               return;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-snvs-allow-a-time-difference-on-clock-register-r.patch b/queue-5.10/rtc-snvs-allow-a-time-difference-on-clock-register-r.patch
new file mode 100644 (file)
index 0000000..a797f34
--- /dev/null
@@ -0,0 +1,92 @@
+From 67457087bdb11562914533ccaee11d56e6f92493 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 6 Nov 2022 12:59:15 +0100
+Subject: rtc: snvs: Allow a time difference on clock register read
+
+From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+
+[ Upstream commit 0462681e207ccc44778a77b3297af728b1cf5b9f ]
+
+On an iMX6ULL the following message appears when a wakealarm is set:
+
+echo 0 > /sys/class/rtc/rtc1/wakealarm
+rtc rtc1: Timeout trying to get valid LPSRT Counter read
+
+This does not always happen but is reproducible quite often (7 out of 10
+times). The problem appears because the iMX6ULL is not able to read the
+registers within one 32kHz clock cycle which is the base clock of the
+RTC. Therefore, this patch allows a difference of up to 320 cycles
+(10ms). 10ms was chosen to be big enough even on systems with less cpu
+power (e.g. iMX6ULL). According to the reference manual a difference is
+fine:
+- If the two consecutive reads are similar, the value is correct.
+The values have to be similar, not equal.
+
+Fixes: cd7f3a249dbe ("rtc: snvs: Add timeouts to avoid kernel lockups")
+Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+Signed-off-by: Francesco Dolcini <francesco@dolcini.it>
+Link: https://lore.kernel.org/r/20221106115915.7930-1-francesco@dolcini.it
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-snvs.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
+index 0263d996b8a8..cc7f6c4216bc 100644
+--- a/drivers/rtc/rtc-snvs.c
++++ b/drivers/rtc/rtc-snvs.c
+@@ -32,6 +32,14 @@
+ #define SNVS_LPPGDR_INIT      0x41736166
+ #define CNTR_TO_SECS_SH               15
++/* The maximum RTC clock cycles that are allowed to pass between two
++ * consecutive clock counter register reads. If the values are corrupted a
++ * bigger difference is expected. The RTC frequency is 32kHz. With 320 cycles
++ * we end at 10ms which should be enough for most cases. If it once takes
++ * longer than expected we do a retry.
++ */
++#define MAX_RTC_READ_DIFF_CYCLES      320
++
+ struct snvs_rtc_data {
+       struct rtc_device *rtc;
+       struct regmap *regmap;
+@@ -56,6 +64,7 @@ static u64 rtc_read_lpsrt(struct snvs_rtc_data *data)
+ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
+ {
+       u64 read1, read2;
++      s64 diff;
+       unsigned int timeout = 100;
+       /* As expected, the registers might update between the read of the LSB
+@@ -66,7 +75,8 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
+       do {
+               read2 = read1;
+               read1 = rtc_read_lpsrt(data);
+-      } while (read1 != read2 && --timeout);
++              diff = read1 - read2;
++      } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout);
+       if (!timeout)
+               dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
+@@ -78,13 +88,15 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
+ static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb)
+ {
+       u32 count1, count2;
++      s32 diff;
+       unsigned int timeout = 100;
+       regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
+       do {
+               count2 = count1;
+               regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
+-      } while (count1 != count2 && --timeout);
++              diff = count1 - count2;
++      } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout);
+       if (!timeout) {
+               dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
+               return -ETIMEDOUT;
+-- 
+2.35.1
+
diff --git a/queue-5.10/rtc-st-lpc-add-missing-clk_disable_unprepare-in-st_r.patch b/queue-5.10/rtc-st-lpc-add-missing-clk_disable_unprepare-in-st_r.patch
new file mode 100644 (file)
index 0000000..8770f4a
--- /dev/null
@@ -0,0 +1,36 @@
+From 65c75807fa721522629d9a25010518f6b3ffbcae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 09:48:05 +0800
+Subject: rtc: st-lpc: Add missing clk_disable_unprepare in st_rtc_probe()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 5fb733d7bd6949e90028efdce8bd528c6ab7cf1e ]
+
+The clk_disable_unprepare() should be called in the error handling
+of clk_get_rate(), fix it.
+
+Fixes: b5b2bdfc2893 ("rtc: st: Add new driver for ST's LPC RTC")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Link: https://lore.kernel.org/r/20221123014805.1993052-1-cuigaosheng1@huawei.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-st-lpc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
+index 0c65448b85ee..7d53f7e2febc 100644
+--- a/drivers/rtc/rtc-st-lpc.c
++++ b/drivers/rtc/rtc-st-lpc.c
+@@ -238,6 +238,7 @@ static int st_rtc_probe(struct platform_device *pdev)
+       rtc->clkrate = clk_get_rate(rtc->clk);
+       if (!rtc->clkrate) {
++              clk_disable_unprepare(rtc->clk);
+               dev_err(&pdev->dev, "Unable to fetch clock rate\n");
+               return -EINVAL;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/rxrpc-fix-ack.buffersize-to-be-0-when-generating-an-.patch b/queue-5.10/rxrpc-fix-ack.buffersize-to-be-0-when-generating-an-.patch
new file mode 100644 (file)
index 0000000..4d99468
--- /dev/null
@@ -0,0 +1,37 @@
+From 7e7148448105df2a090861f9c46edbcf7406c5c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Sep 2022 19:17:29 +0100
+Subject: rxrpc: Fix ack.bufferSize to be 0 when generating an ack
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 8889a711f9b4dcf4dd1330fa493081beebd118c9 ]
+
+ack.bufferSize should be set to 0 when generating an ack.
+
+Fixes: 8d94aa381dab ("rxrpc: Calls shouldn't hold socket refs")
+Reported-by: Jeffrey Altman <jaltman@auristor.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/output.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
+index 9683617db704..08c117bc083e 100644
+--- a/net/rxrpc/output.c
++++ b/net/rxrpc/output.c
+@@ -93,7 +93,7 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn,
+       *_hard_ack = hard_ack;
+       *_top = top;
+-      pkt->ack.bufferSpace    = htons(8);
++      pkt->ack.bufferSpace    = htons(0);
+       pkt->ack.maxSkew        = htons(0);
+       pkt->ack.firstPacket    = htonl(hard_ack + 1);
+       pkt->ack.previousPacket = htonl(call->ackr_highest_seq);
+-- 
+2.35.1
+
diff --git a/queue-5.10/rxrpc-fix-missing-unlock-in-rxrpc_do_sendmsg.patch b/queue-5.10/rxrpc-fix-missing-unlock-in-rxrpc_do_sendmsg.patch
new file mode 100644 (file)
index 0000000..c1a59be
--- /dev/null
@@ -0,0 +1,47 @@
+From 89c27ef0928d94fe3be2ede71ccc9fe6ce468f55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Dec 2022 16:19:47 +0000
+Subject: rxrpc: Fix missing unlock in rxrpc_do_sendmsg()
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 4feb2c44629e6f9b459b41a5a60491069d346a95 ]
+
+One of the error paths in rxrpc_do_sendmsg() doesn't unlock the call mutex
+before returning.  Fix it to do this.
+
+Note that this still doesn't get rid of the checker warning:
+
+   ../net/rxrpc/sendmsg.c:617:5: warning: context imbalance in 'rxrpc_do_sendmsg' - wrong count at exit
+
+I think the interplay between the socket lock and the call's user_mutex may
+be too complicated for checker to analyse, especially as
+rxrpc_new_client_call_for_sendmsg(), which it calls, returns with the
+call's user_mutex if successful but unconditionally drops the socket lock.
+
+Fixes: e754eba685aa ("rxrpc: Provide a cmsg to specify the amount of Tx data for a call")
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/sendmsg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
+index eef3c14fd1c1..a670553159ab 100644
+--- a/net/rxrpc/sendmsg.c
++++ b/net/rxrpc/sendmsg.c
+@@ -733,7 +733,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
+                       if (call->tx_total_len != -1 ||
+                           call->tx_pending ||
+                           call->tx_top != 0)
+-                              goto error_put;
++                              goto out_put_unlock;
+                       call->tx_total_len = p.call.tx_total_len;
+               }
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/s390-ctcm-fix-return-type-of-ctc-mp-m_tx.patch b/queue-5.10/s390-ctcm-fix-return-type-of-ctc-mp-m_tx.patch
new file mode 100644 (file)
index 0000000..a3a9f93
--- /dev/null
@@ -0,0 +1,76 @@
+From 1c65ab8c07d936ef60853de7f81624f4dc242ed7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Nov 2022 10:01:28 -0700
+Subject: s390/ctcm: Fix return type of ctc{mp,}m_tx()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit aa5bf80c3c067b82b4362cd6e8e2194623bcaca6 ]
+
+With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
+indirect call targets are validated against the expected function
+pointer prototype to make sure the call target is valid to help mitigate
+ROP attacks. If they are not identical, there is a failure at run time,
+which manifests as either a kernel panic or thread getting killed. A
+proposed warning in clang aims to catch these at compile time, which
+reveals:
+
+  drivers/s390/net/ctcm_main.c:1064:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+          .ndo_start_xmit         = ctcm_tx,
+                                    ^~~~~~~
+  drivers/s390/net/ctcm_main.c:1072:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+          .ndo_start_xmit         = ctcmpc_tx,
+                                    ^~~~~~~~~
+
+->ndo_start_xmit() in 'struct net_device_ops' expects a return type of
+'netdev_tx_t', not 'int'. Adjust the return type of ctc{mp,}m_tx() to
+match the prototype's to resolve the warning and potential CFI failure,
+should s390 select ARCH_SUPPORTS_CFI_CLANG in the future.
+
+Additionally, while in the area, remove a comment block that is no
+longer relevant.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1750
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/net/ctcm_main.c | 11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
+index d06809eac16d..fb0e8f1cabdc 100644
+--- a/drivers/s390/net/ctcm_main.c
++++ b/drivers/s390/net/ctcm_main.c
+@@ -865,16 +865,9 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
+ /**
+  * Start transmission of a packet.
+  * Called from generic network device layer.
+- *
+- *  skb               Pointer to buffer containing the packet.
+- *  dev               Pointer to interface struct.
+- *
+- * returns 0 if packet consumed, !0 if packet rejected.
+- *         Note: If we return !0, then the packet is free'd by
+- *               the generic network layer.
+  */
+ /* first merge version - leaving both functions separated */
+-static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t ctcm_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct ctcm_priv *priv = dev->ml_priv;
+@@ -917,7 +910,7 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
+ }
+ /* unmerged MPC variant of ctcm_tx */
+-static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+       int len = 0;
+       struct ctcm_priv *priv = dev->ml_priv;
+-- 
+2.35.1
+
diff --git a/queue-5.10/s390-lcs-fix-return-type-of-lcs_start_xmit.patch b/queue-5.10/s390-lcs-fix-return-type-of-lcs_start_xmit.patch
new file mode 100644 (file)
index 0000000..e0b613f
--- /dev/null
@@ -0,0 +1,68 @@
+From 8029b144bbcff219fd888869456d438a987258ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Nov 2022 10:01:30 -0700
+Subject: s390/lcs: Fix return type of lcs_start_xmit()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit bb16db8393658e0978c3f0d30ae069e878264fa3 ]
+
+With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
+indirect call targets are validated against the expected function
+pointer prototype to make sure the call target is valid to help mitigate
+ROP attacks. If they are not identical, there is a failure at run time,
+which manifests as either a kernel panic or thread getting killed. A
+proposed warning in clang aims to catch these at compile time, which
+reveals:
+
+  drivers/s390/net/lcs.c:2090:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+          .ndo_start_xmit         = lcs_start_xmit,
+                                    ^~~~~~~~~~~~~~
+  drivers/s390/net/lcs.c:2097:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+          .ndo_start_xmit         = lcs_start_xmit,
+                                    ^~~~~~~~~~~~~~
+
+->ndo_start_xmit() in 'struct net_device_ops' expects a return type of
+'netdev_tx_t', not 'int'. Adjust the return type of lcs_start_xmit() to
+match the prototype's to resolve the warning and potential CFI failure,
+should s390 select ARCH_SUPPORTS_CFI_CLANG in the future.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1750
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/net/lcs.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
+index 06a322bdced6..7e743f4717a9 100644
+--- a/drivers/s390/net/lcs.c
++++ b/drivers/s390/net/lcs.c
+@@ -1518,9 +1518,8 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer)
+ /**
+  * Packet transmit function called by network stack
+  */
+-static int
+-__lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
+-               struct net_device *dev)
++static netdev_tx_t __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
++                                  struct net_device *dev)
+ {
+       struct lcs_header *header;
+       int rc = NETDEV_TX_OK;
+@@ -1581,8 +1580,7 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
+       return rc;
+ }
+-static int
+-lcs_start_xmit(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t lcs_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct lcs_card *card;
+       int rc;
+-- 
+2.35.1
+
diff --git a/queue-5.10/s390-netiucv-fix-return-type-of-netiucv_tx.patch b/queue-5.10/s390-netiucv-fix-return-type-of-netiucv_tx.patch
new file mode 100644 (file)
index 0000000..47e6c69
--- /dev/null
@@ -0,0 +1,63 @@
+From e9cbf752743afd495df1b27e5190ee103b237d03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Nov 2022 10:01:29 -0700
+Subject: s390/netiucv: Fix return type of netiucv_tx()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 88d86d18d7cf7e9137c95f9d212bb9fff8a1b4be ]
+
+With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
+indirect call targets are validated against the expected function
+pointer prototype to make sure the call target is valid to help mitigate
+ROP attacks. If they are not identical, there is a failure at run time,
+which manifests as either a kernel panic or thread getting killed. A
+proposed warning in clang aims to catch these at compile time, which
+reveals:
+
+  drivers/s390/net/netiucv.c:1854:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+          .ndo_start_xmit         = netiucv_tx,
+                                    ^~~~~~~~~~
+
+->ndo_start_xmit() in 'struct net_device_ops' expects a return type of
+'netdev_tx_t', not 'int'. Adjust the return type of netiucv_tx() to
+match the prototype's to resolve the warning and potential CFI failure,
+should s390 select ARCH_SUPPORTS_CFI_CLANG in the future.
+
+Additionally, while in the area, remove a comment block that is no
+longer relevant.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1750
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/net/netiucv.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
+index 260860cf3aa1..a2f403c4ec38 100644
+--- a/drivers/s390/net/netiucv.c
++++ b/drivers/s390/net/netiucv.c
+@@ -1260,15 +1260,8 @@ static int netiucv_close(struct net_device *dev)
+ /**
+  * Start transmission of a packet.
+  * Called from generic network device layer.
+- *
+- * @param skb Pointer to buffer containing the packet.
+- * @param dev Pointer to interface struct.
+- *
+- * @return 0 if packet consumed, !0 if packet rejected.
+- *         Note: If we return !0, then the packet is free'd by
+- *               the generic network layer.
+  */
+-static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t netiucv_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct netiucv_priv *privptr = netdev_priv(dev);
+       int rc;
+-- 
+2.35.1
+
diff --git a/queue-5.10/samples-vfio-mdev-fix-missing-pci_disable_device-in-.patch b/queue-5.10/samples-vfio-mdev-fix-missing-pci_disable_device-in-.patch
new file mode 100644 (file)
index 0000000..4397396
--- /dev/null
@@ -0,0 +1,59 @@
+From d831393b73deaa3d2cf2060109ac660d0c0d437a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 09:33:41 +0800
+Subject: samples: vfio-mdev: Fix missing pci_disable_device() in
+ mdpy_fb_probe()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit d1f0f50fbbbbca1e3e8157e51934613bf88f6d44 ]
+
+Add missing pci_disable_device() in fail path of mdpy_fb_probe().
+Besides, fix missing release functions in mdpy_fb_remove().
+
+Fixes: cacade1946a4 ("sample: vfio mdev display - guest driver")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.com>
+Link: https://lore.kernel.org/r/20221208013341.3999-1-shangxiaojing@huawei.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/vfio-mdev/mdpy-fb.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/samples/vfio-mdev/mdpy-fb.c b/samples/vfio-mdev/mdpy-fb.c
+index 9ec93d90e8a5..4eb7aa11cfbb 100644
+--- a/samples/vfio-mdev/mdpy-fb.c
++++ b/samples/vfio-mdev/mdpy-fb.c
+@@ -109,7 +109,7 @@ static int mdpy_fb_probe(struct pci_dev *pdev,
+       ret = pci_request_regions(pdev, "mdpy-fb");
+       if (ret < 0)
+-              return ret;
++              goto err_disable_dev;
+       pci_read_config_dword(pdev, MDPY_FORMAT_OFFSET, &format);
+       pci_read_config_dword(pdev, MDPY_WIDTH_OFFSET,  &width);
+@@ -191,6 +191,9 @@ static int mdpy_fb_probe(struct pci_dev *pdev,
+ err_release_regions:
+       pci_release_regions(pdev);
++err_disable_dev:
++      pci_disable_device(pdev);
++
+       return ret;
+ }
+@@ -199,7 +202,10 @@ static void mdpy_fb_remove(struct pci_dev *pdev)
+       struct fb_info *info = pci_get_drvdata(pdev);
+       unregister_framebuffer(info);
++      iounmap(info->screen_base);
+       framebuffer_release(info);
++      pci_release_regions(pdev);
++      pci_disable_device(pdev);
+ }
+ static struct pci_device_id mdpy_fb_pci_table[] = {
+-- 
+2.35.1
+
diff --git a/queue-5.10/sched-fair-cleanup-task_util-and-capacity-type.patch b/queue-5.10/sched-fair-cleanup-task_util-and-capacity-type.patch
new file mode 100644 (file)
index 0000000..b559305
--- /dev/null
@@ -0,0 +1,47 @@
+From 2b3e964ecd827083c0351f8a4448a7ec537d5976 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Dec 2021 09:57:55 +0000
+Subject: sched/fair: Cleanup task_util and capacity type
+
+From: Vincent Donnefort <vincent.donnefort@arm.com>
+
+[ Upstream commit ef8df9798d469b7c45c66664550e93469749f1e8 ]
+
+task_util and capacity are comparable unsigned long values. There is no
+need for an intermidiate implicit signed cast.
+
+Signed-off-by: Vincent Donnefort <vincent.donnefort@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20211207095755.859972-1-vincent.donnefort@arm.com
+Stable-dep-of: 48d5e9daa8b7 ("sched/uclamp: Fix relationship between uclamp and migration margin")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index bca0efc03a51..2d3ea0679207 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -4074,7 +4074,8 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
+       trace_sched_util_est_se_tp(&p->se);
+ }
+-static inline int task_fits_capacity(struct task_struct *p, long capacity)
++static inline int task_fits_capacity(struct task_struct *p,
++                                   unsigned long capacity)
+ {
+       return fits_capacity(uclamp_task_util(p), capacity);
+ }
+@@ -6247,7 +6248,7 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
+       return best_cpu;
+ }
+-static inline bool asym_fits_capacity(int task_util, int cpu)
++static inline bool asym_fits_capacity(unsigned long task_util, int cpu)
+ {
+       if (static_branch_unlikely(&sched_asym_cpucapacity))
+               return fits_capacity(task_util, capacity_of(cpu));
+-- 
+2.35.1
+
diff --git a/queue-5.10/sched-uclamp-fix-relationship-between-uclamp-and-mig.patch b/queue-5.10/sched-uclamp-fix-relationship-between-uclamp-and-mig.patch
new file mode 100644 (file)
index 0000000..493da53
--- /dev/null
@@ -0,0 +1,200 @@
+From d596d269046d7e2bdf599bb704fd1114b660ea07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Aug 2022 15:36:01 +0100
+Subject: sched/uclamp: Fix relationship between uclamp and migration margin
+
+From: Qais Yousef <qais.yousef@arm.com>
+
+[ Upstream commit 48d5e9daa8b767e75ed9421665b037a49ce4bc04 ]
+
+fits_capacity() verifies that a util is within 20% margin of the
+capacity of a CPU, which is an attempt to speed up upmigration.
+
+But when uclamp is used, this 20% margin is problematic because for
+example if a task is boosted to 1024, then it will not fit on any CPU
+according to fits_capacity() logic.
+
+Or if a task is boosted to capacity_orig_of(medium_cpu). The task will
+end up on big instead on the desired medium CPU.
+
+Similar corner cases exist for uclamp and usage of capacity_of().
+Slightest irq pressure on biggest CPU for example will make a 1024
+boosted task look like it can't fit.
+
+What we really want is for uclamp comparisons to ignore the migration
+margin and capacity pressure, yet retain them for when checking the
+_actual_ util signal.
+
+For example, task p:
+
+       p->util_avg = 300
+       p->uclamp[UCLAMP_MIN] = 1024
+
+Will fit a big CPU. But
+
+       p->util_avg = 900
+       p->uclamp[UCLAMP_MIN] = 1024
+
+will not, this should trigger overutilized state because the big CPU is
+now *actually* being saturated.
+
+Similar reasoning applies to capping tasks with UCLAMP_MAX. For example:
+
+       p->util_avg = 1024
+       p->uclamp[UCLAMP_MAX] = capacity_orig_of(medium_cpu)
+
+Should fit the task on medium cpus without triggering overutilized
+state.
+
+Inlined comments expand more on desired behavior in more scenarios.
+
+Introduce new util_fits_cpu() function which encapsulates the new logic.
+The new function is not used anywhere yet, but will be used to update
+various users of fits_capacity() in later patches.
+
+Fixes: af24bde8df202 ("sched/uclamp: Add uclamp support to energy_compute()")
+Signed-off-by: Qais Yousef <qais.yousef@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20220804143609.515789-2-qais.yousef@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 123 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 123 insertions(+)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 2d3ea0679207..c39d2fc3f994 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -4074,6 +4074,129 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
+       trace_sched_util_est_se_tp(&p->se);
+ }
++static inline int util_fits_cpu(unsigned long util,
++                              unsigned long uclamp_min,
++                              unsigned long uclamp_max,
++                              int cpu)
++{
++      unsigned long capacity_orig, capacity_orig_thermal;
++      unsigned long capacity = capacity_of(cpu);
++      bool fits, uclamp_max_fits;
++
++      /*
++       * Check if the real util fits without any uclamp boost/cap applied.
++       */
++      fits = fits_capacity(util, capacity);
++
++      if (!uclamp_is_used())
++              return fits;
++
++      /*
++       * We must use capacity_orig_of() for comparing against uclamp_min and
++       * uclamp_max. We only care about capacity pressure (by using
++       * capacity_of()) for comparing against the real util.
++       *
++       * If a task is boosted to 1024 for example, we don't want a tiny
++       * pressure to skew the check whether it fits a CPU or not.
++       *
++       * Similarly if a task is capped to capacity_orig_of(little_cpu), it
++       * should fit a little cpu even if there's some pressure.
++       *
++       * Only exception is for thermal pressure since it has a direct impact
++       * on available OPP of the system.
++       *
++       * We honour it for uclamp_min only as a drop in performance level
++       * could result in not getting the requested minimum performance level.
++       *
++       * For uclamp_max, we can tolerate a drop in performance level as the
++       * goal is to cap the task. So it's okay if it's getting less.
++       *
++       * In case of capacity inversion, which is not handled yet, we should
++       * honour the inverted capacity for both uclamp_min and uclamp_max all
++       * the time.
++       */
++      capacity_orig = capacity_orig_of(cpu);
++      capacity_orig_thermal = capacity_orig - arch_scale_thermal_pressure(cpu);
++
++      /*
++       * We want to force a task to fit a cpu as implied by uclamp_max.
++       * But we do have some corner cases to cater for..
++       *
++       *
++       *                                 C=z
++       *   |                             ___
++       *   |                  C=y       |   |
++       *   |_ _ _ _ _ _ _ _ _ ___ _ _ _ | _ | _ _ _ _ _  uclamp_max
++       *   |      C=x        |   |      |   |
++       *   |      ___        |   |      |   |
++       *   |     |   |       |   |      |   |    (util somewhere in this region)
++       *   |     |   |       |   |      |   |
++       *   |     |   |       |   |      |   |
++       *   +----------------------------------------
++       *         cpu0        cpu1       cpu2
++       *
++       *   In the above example if a task is capped to a specific performance
++       *   point, y, then when:
++       *
++       *   * util = 80% of x then it does not fit on cpu0 and should migrate
++       *     to cpu1
++       *   * util = 80% of y then it is forced to fit on cpu1 to honour
++       *     uclamp_max request.
++       *
++       *   which is what we're enforcing here. A task always fits if
++       *   uclamp_max <= capacity_orig. But when uclamp_max > capacity_orig,
++       *   the normal upmigration rules should withhold still.
++       *
++       *   Only exception is when we are on max capacity, then we need to be
++       *   careful not to block overutilized state. This is so because:
++       *
++       *     1. There's no concept of capping at max_capacity! We can't go
++       *        beyond this performance level anyway.
++       *     2. The system is being saturated when we're operating near
++       *        max capacity, it doesn't make sense to block overutilized.
++       */
++      uclamp_max_fits = (capacity_orig == SCHED_CAPACITY_SCALE) && (uclamp_max == SCHED_CAPACITY_SCALE);
++      uclamp_max_fits = !uclamp_max_fits && (uclamp_max <= capacity_orig);
++      fits = fits || uclamp_max_fits;
++
++      /*
++       *
++       *                                 C=z
++       *   |                             ___       (region a, capped, util >= uclamp_max)
++       *   |                  C=y       |   |
++       *   |_ _ _ _ _ _ _ _ _ ___ _ _ _ | _ | _ _ _ _ _ uclamp_max
++       *   |      C=x        |   |      |   |
++       *   |      ___        |   |      |   |      (region b, uclamp_min <= util <= uclamp_max)
++       *   |_ _ _|_ _|_ _ _ _| _ | _ _ _| _ | _ _ _ _ _ uclamp_min
++       *   |     |   |       |   |      |   |
++       *   |     |   |       |   |      |   |      (region c, boosted, util < uclamp_min)
++       *   +----------------------------------------
++       *         cpu0        cpu1       cpu2
++       *
++       * a) If util > uclamp_max, then we're capped, we don't care about
++       *    actual fitness value here. We only care if uclamp_max fits
++       *    capacity without taking margin/pressure into account.
++       *    See comment above.
++       *
++       * b) If uclamp_min <= util <= uclamp_max, then the normal
++       *    fits_capacity() rules apply. Except we need to ensure that we
++       *    enforce we remain within uclamp_max, see comment above.
++       *
++       * c) If util < uclamp_min, then we are boosted. Same as (b) but we
++       *    need to take into account the boosted value fits the CPU without
++       *    taking margin/pressure into account.
++       *
++       * Cases (a) and (b) are handled in the 'fits' variable already. We
++       * just need to consider an extra check for case (c) after ensuring we
++       * handle the case uclamp_min > uclamp_max.
++       */
++      uclamp_min = min(uclamp_min, uclamp_max);
++      if (util < uclamp_min && capacity_orig != SCHED_CAPACITY_SCALE)
++              fits = fits && (uclamp_min <= capacity_orig_thermal);
++
++      return fits;
++}
++
+ static inline int task_fits_capacity(struct task_struct *p,
+                                    unsigned long capacity)
+ {
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-core-fix-a-race-between-scsi_done-and-scsi_time.patch b/queue-5.10/scsi-core-fix-a-race-between-scsi_done-and-scsi_time.patch
new file mode 100644 (file)
index 0000000..48c927f
--- /dev/null
@@ -0,0 +1,64 @@
+From 516990cbf51e19ff950752ccb239e0fce36ec42f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 13:29:49 -0700
+Subject: scsi: core: Fix a race between scsi_done() and scsi_timeout()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 978b7922d3dca672b41bb4b8ce6c06ab77112741 ]
+
+If there is a race between scsi_done() and scsi_timeout() and if
+scsi_timeout() loses the race, scsi_timeout() should not reset the request
+timer. Hence change the return value for this case from BLK_EH_RESET_TIMER
+into BLK_EH_DONE.
+
+Although the block layer holds a reference on a request (req->ref) while
+calling a timeout handler, restarting the timer (blk_add_timer()) while a
+request is being completed is racy.
+
+Reviewed-by: Mike Christie <michael.christie@oracle.com>
+Cc: Keith Busch <kbusch@kernel.org>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Ming Lei <ming.lei@redhat.com>
+Cc: John Garry <john.garry@huawei.com>
+Cc: Hannes Reinecke <hare@suse.de>
+Reported-by: Adrian Hunter <adrian.hunter@intel.com>
+Fixes: 15f73f5b3e59 ("blk-mq: move failure injection out of blk_mq_complete_request")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20221018202958.1902564-2-bvanassche@acm.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_error.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index f11f51e2465f..0c4bc42b55c2 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -306,19 +306,11 @@ enum blk_eh_timer_return scsi_times_out(struct request *req)
+       if (rtn == BLK_EH_DONE) {
+               /*
+-               * Set the command to complete first in order to prevent a real
+-               * completion from releasing the command while error handling
+-               * is using it. If the command was already completed, then the
+-               * lower level driver beat the timeout handler, and it is safe
+-               * to return without escalating error recovery.
+-               *
+-               * If timeout handling lost the race to a real completion, the
+-               * block layer may ignore that due to a fake timeout injection,
+-               * so return RESET_TIMER to allow error handling another shot
+-               * at this command.
++               * If scsi_done() has already set SCMD_STATE_COMPLETE, do not
++               * modify *scmd.
+                */
+               if (test_and_set_bit(SCMD_STATE_COMPLETE, &scmd->state))
+-                      return BLK_EH_RESET_TIMER;
++                      return BLK_EH_DONE;
+               if (scsi_abort_command(scmd) != SUCCESS) {
+                       set_host_byte(scmd, DID_TIME_OUT);
+                       scsi_eh_scmd_add(scmd);
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-fcoe-fix-possible-name-leak-when-device_registe.patch b/queue-5.10/scsi-fcoe-fix-possible-name-leak-when-device_registe.patch
new file mode 100644 (file)
index 0000000..953e0c9
--- /dev/null
@@ -0,0 +1,78 @@
+From ad649f33e9afb7ef2661d1815e9b3e05d10719f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Nov 2022 17:43:10 +0800
+Subject: scsi: fcoe: Fix possible name leak when device_register() fails
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 47b6a122c7b69a876c7ee2fc064a26b09627de9d ]
+
+If device_register() returns an error, the name allocated by dev_set_name()
+needs to be freed. As the comment of device_register() says, one should use
+put_device() to give up the reference in the error path. Fix this by
+calling put_device(), then the name can be freed in kobject_cleanup().
+
+The 'fcf' is freed in fcoe_fcf_device_release(), so the kfree() in the
+error path can be removed.
+
+The 'ctlr' is freed in fcoe_ctlr_device_release(), so don't use the error
+label, just return NULL after calling put_device().
+
+Fixes: 9a74e884ee71 ("[SCSI] libfcoe: Add fcoe_sysfs")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221112094310.3633291-1-yangyingliang@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/fcoe/fcoe_sysfs.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/scsi/fcoe/fcoe_sysfs.c b/drivers/scsi/fcoe/fcoe_sysfs.c
+index ffef2c8eddc6..68d8027d5108 100644
+--- a/drivers/scsi/fcoe/fcoe_sysfs.c
++++ b/drivers/scsi/fcoe/fcoe_sysfs.c
+@@ -830,14 +830,15 @@ struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent,
+       dev_set_name(&ctlr->dev, "ctlr_%d", ctlr->id);
+       error = device_register(&ctlr->dev);
+-      if (error)
+-              goto out_del_q2;
++      if (error) {
++              destroy_workqueue(ctlr->devloss_work_q);
++              destroy_workqueue(ctlr->work_q);
++              put_device(&ctlr->dev);
++              return NULL;
++      }
+       return ctlr;
+-out_del_q2:
+-      destroy_workqueue(ctlr->devloss_work_q);
+-      ctlr->devloss_work_q = NULL;
+ out_del_q:
+       destroy_workqueue(ctlr->work_q);
+       ctlr->work_q = NULL;
+@@ -1036,16 +1037,16 @@ struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *ctlr,
+       fcf->selected = new_fcf->selected;
+       error = device_register(&fcf->dev);
+-      if (error)
+-              goto out_del;
++      if (error) {
++              put_device(&fcf->dev);
++              goto out;
++      }
+       fcf->state = FCOE_FCF_STATE_CONNECTED;
+       list_add_tail(&fcf->peers, &ctlr->fcfs);
+       return fcf;
+-out_del:
+-      kfree(fcf);
+ out:
+       return NULL;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-fcoe-fix-transport-not-deattached-when-fcoe_if_.patch b/queue-5.10/scsi-fcoe-fix-transport-not-deattached-when-fcoe_if_.patch
new file mode 100644 (file)
index 0000000..c10792b
--- /dev/null
@@ -0,0 +1,46 @@
+From df6a6e758ddc7f25769c47996c261216abee4df2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 17:24:42 +0800
+Subject: scsi: fcoe: Fix transport not deattached when fcoe_if_init() fails
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit 4155658cee394b22b24c6d64e49247bf26d95b92 ]
+
+fcoe_init() calls fcoe_transport_attach(&fcoe_sw_transport), but when
+fcoe_if_init() fails, &fcoe_sw_transport is not detached and leaves freed
+&fcoe_sw_transport on fcoe_transports list. This causes panic when
+reinserting module.
+
+ BUG: unable to handle page fault for address: fffffbfff82e2213
+ RIP: 0010:fcoe_transport_attach+0xe1/0x230 [libfcoe]
+ Call Trace:
+  <TASK>
+  do_one_initcall+0xd0/0x4e0
+  load_module+0x5eee/0x7210
+  ...
+
+Fixes: 78a582463c1e ("[SCSI] fcoe: convert fcoe.ko to become an fcoe transport provider driver")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Link: https://lore.kernel.org/r/20221115092442.133088-1-chenzhongjin@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/fcoe/fcoe.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
+index 0f9274960dc6..30afcbbe1f86 100644
+--- a/drivers/scsi/fcoe/fcoe.c
++++ b/drivers/scsi/fcoe/fcoe.c
+@@ -2504,6 +2504,7 @@ static int __init fcoe_init(void)
+ out_free:
+       mutex_unlock(&fcoe_config_mutex);
++      fcoe_transport_detach(&fcoe_sw_transport);
+ out_destroy:
+       destroy_workqueue(fcoe_wq);
+       return rc;
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-hpsa-fix-error-handling-in-hpsa_add_sas_host.patch b/queue-5.10/scsi-hpsa-fix-error-handling-in-hpsa_add_sas_host.patch
new file mode 100644 (file)
index 0000000..4d068b6
--- /dev/null
@@ -0,0 +1,54 @@
+From eb354ab199ef34e2ce95adc179c6d5d574694ab3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 23:11:29 +0800
+Subject: scsi: hpsa: Fix error handling in hpsa_add_sas_host()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 4ef174a3ad9b5d73c1b6573e244ebba2b0d86eac ]
+
+hpsa_sas_port_add_phy() does:
+  ...
+  sas_phy_add()  -> may return error here
+  sas_port_add_phy()
+  ...
+
+Whereas hpsa_free_sas_phy() does:
+  ...
+  sas_port_delete_phy()
+  sas_phy_delete()
+  ...
+
+If hpsa_sas_port_add_phy() returns an error, hpsa_free_sas_phy() can not be
+called to free the memory because the port and the phy have not been added
+yet.
+
+Replace hpsa_free_sas_phy() with sas_phy_free() and kfree() to avoid kernel
+crash in this case.
+
+Fixes: d04e62b9d63a ("hpsa: add in sas transport class")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221110151129.394389-1-yangyingliang@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hpsa.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index cd78d77911cd..48be84b4e95c 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -9764,7 +9764,8 @@ static int hpsa_add_sas_host(struct ctlr_info *h)
+       return 0;
+ free_sas_phy:
+-      hpsa_free_sas_phy(hpsa_sas_phy);
++      sas_phy_free(hpsa_sas_phy->phy);
++      kfree(hpsa_sas_phy);
+ free_sas_port:
+       hpsa_free_sas_port(hpsa_sas_port);
+ free_sas_node:
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-hpsa-fix-possible-memory-leak-in-hpsa_add_sas_d.patch b/queue-5.10/scsi-hpsa-fix-possible-memory-leak-in-hpsa_add_sas_d.patch
new file mode 100644 (file)
index 0000000..9d9f833
--- /dev/null
@@ -0,0 +1,43 @@
+From 1b60247ed5e186123fa1888fa4892fc6ca3edbb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 12:30:12 +0800
+Subject: scsi: hpsa: Fix possible memory leak in hpsa_add_sas_device()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit fda34a5d304d0b98cc967e8763b52221b66dc202 ]
+
+If hpsa_sas_port_add_rphy() returns an error, the 'rphy' allocated in
+sas_end_device_alloc() needs to be freed. Address this by calling
+sas_rphy_free() in the error path.
+
+Fixes: d04e62b9d63a ("hpsa: add in sas transport class")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221111043012.1074466-1-yangyingliang@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hpsa.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 48be84b4e95c..b2d4b6c78b5c 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -9801,10 +9801,12 @@ static int hpsa_add_sas_device(struct hpsa_sas_node *hpsa_sas_node,
+       rc = hpsa_sas_port_add_rphy(hpsa_sas_port, rphy);
+       if (rc)
+-              goto free_sas_port;
++              goto free_sas_rphy;
+       return 0;
++free_sas_rphy:
++      sas_rphy_free(rphy);
+ free_sas_port:
+       hpsa_free_sas_port(hpsa_sas_port);
+       device->sas_port = NULL;
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-hpsa-fix-possible-memory-leak-in-hpsa_init_one.patch b/queue-5.10/scsi-hpsa-fix-possible-memory-leak-in-hpsa_init_one.patch
new file mode 100644 (file)
index 0000000..927488f
--- /dev/null
@@ -0,0 +1,42 @@
+From 998c61b0e517f4abd69621cbe4e1cf51b9daf93d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 01:57:51 +0000
+Subject: scsi: hpsa: Fix possible memory leak in hpsa_init_one()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 9c9ff300e0de07475796495d86f449340d454a0c ]
+
+The hpda_alloc_ctlr_info() allocates h and its field reply_map. However, in
+hpsa_init_one(), if alloc_percpu() failed, the hpsa_init_one() jumps to
+clean1 directly, which frees h and leaks the h->reply_map.
+
+Fix by calling hpda_free_ctlr_info() to release h->replay_map and h instead
+free h directly.
+
+Fixes: 8b834bff1b73 ("scsi: hpsa: fix selection of reply queue")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Link: https://lore.kernel.org/r/20221122015751.87284-1-yuancan@huawei.com
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hpsa.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 8df70c92911d..cd78d77911cd 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -8904,7 +8904,7 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+               destroy_workqueue(h->monitor_ctlr_wq);
+               h->monitor_ctlr_wq = NULL;
+       }
+-      kfree(h);
++      hpda_free_ctlr_info(h);
+       return rc;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-ipr-fix-warning-in-ipr_init.patch b/queue-5.10/scsi-ipr-fix-warning-in-ipr_init.patch
new file mode 100644 (file)
index 0000000..1a7a8f2
--- /dev/null
@@ -0,0 +1,73 @@
+From aec1850a106ac1822247346bed7ae0fbeead4551 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Nov 2022 14:45:13 +0800
+Subject: scsi: ipr: Fix WARNING in ipr_init()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit e6f108bffc3708ddcff72324f7d40dfcd0204894 ]
+
+ipr_init() will not call unregister_reboot_notifier() when
+pci_register_driver() fails, which causes a WARNING. Call
+unregister_reboot_notifier() when pci_register_driver() fails.
+
+notifier callback ipr_halt [ipr] already registered
+WARNING: CPU: 3 PID: 299 at kernel/notifier.c:29
+notifier_chain_register+0x16d/0x230
+Modules linked in: ipr(+) xhci_pci_renesas xhci_hcd ehci_hcd usbcore
+led_class gpu_sched drm_buddy video wmi drm_ttm_helper ttm
+drm_display_helper drm_kms_helper drm drm_panel_orientation_quirks
+agpgart cfbft
+CPU: 3 PID: 299 Comm: modprobe Tainted: G        W
+6.1.0-rc1-00190-g39508d23b672-dirty #332
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
+rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014
+RIP: 0010:notifier_chain_register+0x16d/0x230
+Call Trace:
+ <TASK>
+ __blocking_notifier_chain_register+0x73/0xb0
+ ipr_init+0x30/0x1000 [ipr]
+ do_one_initcall+0xdb/0x480
+ do_init_module+0x1cf/0x680
+ load_module+0x6a50/0x70a0
+ __do_sys_finit_module+0x12f/0x1c0
+ do_syscall_64+0x3f/0x90
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Fixes: f72919ec2bbb ("[SCSI] ipr: implement shutdown changes and remove obsolete write cache parameter")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.com>
+Link: https://lore.kernel.org/r/20221113064513.14028-1-shangxiaojing@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/ipr.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
+index 90e8a538b078..a5e6fbd86ad4 100644
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -10870,11 +10870,19 @@ static struct notifier_block ipr_notifier = {
+  **/
+ static int __init ipr_init(void)
+ {
++      int rc;
++
+       ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n",
+                IPR_DRIVER_VERSION, IPR_DRIVER_DATE);
+       register_reboot_notifier(&ipr_notifier);
+-      return pci_register_driver(&ipr_driver);
++      rc = pci_register_driver(&ipr_driver);
++      if (rc) {
++              unregister_reboot_notifier(&ipr_notifier);
++              return rc;
++      }
++
++      return 0;
+ }
+ /**
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-mpt3sas-fix-possible-resource-leaks-in-mpt3sas_.patch b/queue-5.10/scsi-mpt3sas-fix-possible-resource-leaks-in-mpt3sas_.patch
new file mode 100644 (file)
index 0000000..2c25adf
--- /dev/null
@@ -0,0 +1,67 @@
+From 2a8dbcaf8329e796809f6a9cddfb5538a1a429fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 11:24:03 +0800
+Subject: scsi: mpt3sas: Fix possible resource leaks in
+ mpt3sas_transport_port_add()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 78316e9dfc24906dd474630928ed1d3c562b568e ]
+
+In mpt3sas_transport_port_add(), if sas_rphy_add() returns error,
+sas_rphy_free() needs be called to free the resource allocated in
+sas_end_device_alloc(). Otherwise a kernel crash will happen:
+
+Unable to handle kernel NULL pointer dereference at virtual address 0000000000000108
+CPU: 45 PID: 37020 Comm: bash Kdump: loaded Tainted: G        W          6.1.0-rc1+ #189
+pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : device_del+0x54/0x3d0
+lr : device_del+0x37c/0x3d0
+Call trace:
+ device_del+0x54/0x3d0
+ attribute_container_class_device_del+0x28/0x38
+ transport_remove_classdev+0x6c/0x80
+ attribute_container_device_trigger+0x108/0x110
+ transport_remove_device+0x28/0x38
+ sas_rphy_remove+0x50/0x78 [scsi_transport_sas]
+ sas_port_delete+0x30/0x148 [scsi_transport_sas]
+ do_sas_phy_delete+0x78/0x80 [scsi_transport_sas]
+ device_for_each_child+0x68/0xb0
+ sas_remove_children+0x30/0x50 [scsi_transport_sas]
+ sas_rphy_remove+0x38/0x78 [scsi_transport_sas]
+ sas_port_delete+0x30/0x148 [scsi_transport_sas]
+ do_sas_phy_delete+0x78/0x80 [scsi_transport_sas]
+ device_for_each_child+0x68/0xb0
+ sas_remove_children+0x30/0x50 [scsi_transport_sas]
+ sas_remove_host+0x20/0x38 [scsi_transport_sas]
+ scsih_remove+0xd8/0x420 [mpt3sas]
+
+Because transport_add_device() is not called when sas_rphy_add() fails, the
+device is not added. When sas_rphy_remove() is subsequently called to
+remove the device in the remove() path, a NULL pointer dereference happens.
+
+Fixes: f92363d12359 ("[SCSI] mpt3sas: add new driver supporting 12GB SAS")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221109032403.1636422-1-yangyingliang@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpt3sas/mpt3sas_transport.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c
+index 6ec5b7f33dfd..b58f4d9c296a 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
+@@ -712,6 +712,8 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
+       if ((sas_rphy_add(rphy))) {
+               ioc_err(ioc, "failure at %s:%d/%s()!\n",
+                       __FILE__, __LINE__, __func__);
++              sas_rphy_free(rphy);
++              rphy = NULL;
+       }
+       if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-scsi_debug-fix-a-warning-in-resp_report_zones.patch b/queue-5.10/scsi-scsi_debug-fix-a-warning-in-resp_report_zones.patch
new file mode 100644 (file)
index 0000000..c2589e0
--- /dev/null
@@ -0,0 +1,41 @@
+From b3cfca67a9656c135c385cb121b26a10096b4948 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 23:06:12 -0800
+Subject: scsi: scsi_debug: Fix a warning in resp_report_zones()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit 07f2ca139d9a7a1ba71c4c03997c8de161db2346 ]
+
+As 'alloc_len' is user controlled data, if user tries to allocate memory
+larger than(>=) MAX_ORDER, then kcalloc() will fail, it creates a stack
+trace and messes up dmesg with a warning.
+
+Add __GFP_NOWARN in order to avoid too large allocation warning.  This is
+detected by static analysis using smatch.
+
+Fixes: 7db0e0c8190a ("scsi: scsi_debug: Fix buffer size of REPORT ZONES command")
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Link: https://lore.kernel.org/r/20221112070612.2121535-1-harshit.m.mogalapalli@oracle.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index cdbcb5eaf279..bd63357f439d 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -4346,7 +4346,7 @@ static int resp_report_zones(struct scsi_cmnd *scp,
+       rep_max_zones = min((alloc_len - 64) >> ilog2(RZONES_DESC_HD),
+                           max_zones);
+-      arr = kzalloc(alloc_len, GFP_ATOMIC);
++      arr = kzalloc(alloc_len, GFP_ATOMIC | __GFP_NOWARN);
+       if (!arr) {
+               mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC,
+                               INSUFF_RES_ASCQ);
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-scsi_debug-fix-a-warning-in-resp_verify.patch b/queue-5.10/scsi-scsi_debug-fix-a-warning-in-resp_verify.patch
new file mode 100644 (file)
index 0000000..919b30d
--- /dev/null
@@ -0,0 +1,41 @@
+From 1dd417331f4be9b645ae625fb7683fd168178a1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 23:00:31 -0800
+Subject: scsi: scsi_debug: Fix a warning in resp_verify()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit ed0f17b748b20271cb568c7ca0b23b120316a47d ]
+
+As 'vnum' is controlled by user, so if user tries to allocate memory larger
+than(>=) MAX_ORDER, then kcalloc() will fail, it creates a stack trace and
+messes up dmesg with a warning.
+
+Add __GFP_NOWARN in order to avoid too large allocation warning.  This is
+detected by static analysis using smatch.
+
+Fixes: c3e2fe9222d4 ("scsi: scsi_debug: Implement VERIFY(10), add VERIFY(16)")
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Link: https://lore.kernel.org/r/20221112070031.2121068-1-harshit.m.mogalapalli@oracle.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index 110d0e7f9413..cdbcb5eaf279 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -4275,7 +4275,7 @@ static int resp_verify(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
+       if (ret)
+               return ret;
+-      arr = kcalloc(lb_size, vnum, GFP_ATOMIC);
++      arr = kcalloc(lb_size, vnum, GFP_ATOMIC | __GFP_NOWARN);
+       if (!arr) {
+               mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC,
+                               INSUFF_RES_ASCQ);
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-scsi_debug-fix-a-warning-in-resp_write_scat.patch b/queue-5.10/scsi-scsi_debug-fix-a-warning-in-resp_write_scat.patch
new file mode 100644 (file)
index 0000000..07f1146
--- /dev/null
@@ -0,0 +1,66 @@
+From 39ce3c074ad29ac9e49eb5aee0bceae8be5a8010 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 02:05:25 -0800
+Subject: scsi: scsi_debug: Fix a warning in resp_write_scat()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit 216e179724c1d9f57a8ababf8bd7aaabef67f01b ]
+
+As 'lbdof_blen' is coming from user, if the size in kzalloc() is >=
+MAX_ORDER then we hit a warning.
+
+Call trace:
+
+sg_ioctl
+ sg_ioctl_common
+   scsi_ioctl
+    sg_scsi_ioctl
+     blk_execute_rq
+      blk_mq_sched_insert_request
+       blk_mq_run_hw_queue
+        __blk_mq_delay_run_hw_queue
+         __blk_mq_run_hw_queue
+          blk_mq_sched_dispatch_requests
+           __blk_mq_sched_dispatch_requests
+            blk_mq_dispatch_rq_list
+             scsi_queue_rq
+              scsi_dispatch_cmd
+               scsi_debug_queuecommand
+                schedule_resp
+                 resp_write_scat
+
+If you try to allocate a memory larger than(>=) MAX_ORDER, then kmalloc()
+will definitely fail.  It creates a stack trace and messes up dmesg.  The
+user controls the size here so if they specify a too large size it will
+fail.
+
+Add __GFP_NOWARN in order to avoid too large allocation warning.  This is
+detected by static analysis using smatch.
+
+Fixes: 481b5e5c7949 ("scsi: scsi_debug: add resp_write_scat function")
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Link: https://lore.kernel.org/r/20221111100526.1790533-1-harshit.m.mogalapalli@oracle.com
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index cc20621bb49d..110d0e7f9413 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -3619,7 +3619,7 @@ static int resp_write_scat(struct scsi_cmnd *scp,
+               mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0);
+               return illegal_condition_result;
+       }
+-      lrdp = kzalloc(lbdof_blen, GFP_ATOMIC);
++      lrdp = kzalloc(lbdof_blen, GFP_ATOMIC | __GFP_NOWARN);
+       if (lrdp == NULL)
+               return SCSI_MLQUEUE_HOST_BUSY;
+       if (sdebug_verbose)
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-scsi_debug-fix-possible-name-leak-in-sdebug_add.patch b/queue-5.10/scsi-scsi_debug-fix-possible-name-leak-in-sdebug_add.patch
new file mode 100644 (file)
index 0000000..b3ae6f8
--- /dev/null
@@ -0,0 +1,49 @@
+From de1168d952c328025234f6ae4ee0f641505cadfb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Nov 2022 21:10:10 +0800
+Subject: scsi: scsi_debug: Fix possible name leak in sdebug_add_host_helper()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit e6d773f93a49e0eda88a903a2a6542ca83380eb1 ]
+
+Afer commit 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id
+string array"), the name of device is allocated dynamically, it needs be
+freed when device_register() returns error.
+
+As comment of device_register() says, one should use put_device() to give
+up the reference in the error path. Fix this by calling put_device(), then
+the name can be freed in kobject_cleanup(), and sdbg_host is freed in
+sdebug_release_adapter().
+
+When the device release is not set, it means the device is not initialized.
+We can not call put_device() in this case. Use kfree() to free memory.
+
+Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221112131010.3757845-1-yangyingliang@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_debug.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index bd63357f439d..7cfc6db81763 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -7103,7 +7103,10 @@ static int sdebug_add_host_helper(int per_host_idx)
+               kfree(sdbg_devinfo->zstate);
+               kfree(sdbg_devinfo);
+       }
+-      kfree(sdbg_host);
++      if (sdbg_host->dev.release)
++              put_device(&sdbg_host->dev);
++      else
++              kfree(sdbg_host);
+       pr_warn("%s: failed, errno=%d\n", __func__, -error);
+       return error;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/scsi-snic-fix-possible-uaf-in-snic_tgt_create.patch b/queue-5.10/scsi-snic-fix-possible-uaf-in-snic_tgt_create.patch
new file mode 100644 (file)
index 0000000..fceea89
--- /dev/null
@@ -0,0 +1,47 @@
+From 644b28530526744d0d88f30d35e30ce1db9f4fbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 11:51:00 +0800
+Subject: scsi: snic: Fix possible UAF in snic_tgt_create()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit e118df492320176af94deec000ae034cc92be754 ]
+
+Smatch reports a warning as follows:
+
+drivers/scsi/snic/snic_disc.c:307 snic_tgt_create() warn:
+  '&tgt->list' not removed from list
+
+If device_add() fails in snic_tgt_create(), tgt will be freed, but
+tgt->list will not be removed from snic->disc.tgt_list, then list traversal
+may cause UAF.
+
+Remove from snic->disc.tgt_list before free().
+
+Fixes: c8806b6c9e82 ("snic: driver for Cisco SCSI HBA")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Link: https://lore.kernel.org/r/20221117035100.2944812-1-cuigaosheng1@huawei.com
+Acked-by: Narsimhulu Musini <nmusini@cisco.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/snic/snic_disc.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/snic/snic_disc.c b/drivers/scsi/snic/snic_disc.c
+index e9ccfb97773f..7cf871323b2c 100644
+--- a/drivers/scsi/snic/snic_disc.c
++++ b/drivers/scsi/snic/snic_disc.c
+@@ -318,6 +318,9 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid)
+                             ret);
+               put_device(&snic->shost->shost_gendev);
++              spin_lock_irqsave(snic->shost->host_lock, flags);
++              list_del(&tgt->list);
++              spin_unlock_irqrestore(snic->shost->host_lock, flags);
+               kfree(tgt);
+               tgt = NULL;
+-- 
+2.35.1
+
diff --git a/queue-5.10/sctp-sysctl-make-extra-pointers-netns-aware.patch b/queue-5.10/sctp-sysctl-make-extra-pointers-netns-aware.patch
new file mode 100644 (file)
index 0000000..2d08a9b
--- /dev/null
@@ -0,0 +1,166 @@
+From 86da4e9474652d831cd496cb49597b3603548ef8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 13:48:54 +0800
+Subject: sctp: sysctl: make extra pointers netns aware
+
+From: Firo Yang <firo.yang@suse.com>
+
+[ Upstream commit da05cecc4939c0410d56c29e252998b192756318 ]
+
+Recently, a customer reported that from their container whose
+net namespace is different to the host's init_net, they can't set
+the container's net.sctp.rto_max to any value smaller than
+init_net.sctp.rto_min.
+
+For instance,
+Host:
+sudo sysctl net.sctp.rto_min
+net.sctp.rto_min = 1000
+
+Container:
+echo 100 > /mnt/proc-net/sctp/rto_min
+echo 400 > /mnt/proc-net/sctp/rto_max
+echo: write error: Invalid argument
+
+This is caused by the check made from this'commit 4f3fdf3bc59c
+("sctp: add check rto_min and rto_max in sysctl")'
+When validating the input value, it's always referring the boundary
+value set for the init_net namespace.
+
+Having container's rto_max smaller than host's init_net.sctp.rto_min
+does make sense. Consider that the rto between two containers on the
+same host is very likely smaller than it for two hosts.
+
+So to fix this problem, as suggested by Marcelo, this patch makes the
+extra pointers of rto_min, rto_max, pf_retrans, and ps_retrans point
+to the corresponding variables from the newly created net namespace while
+the new net namespace is being registered in sctp_sysctl_net_register.
+
+Fixes: 4f3fdf3bc59c ("sctp: add check rto_min and rto_max in sysctl")
+Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Reviewed-by: Jakub Kicinski <kuba@kernel.org>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: Firo Yang <firo.yang@suse.com>
+Link: https://lore.kernel.org/r/20221209054854.23889-1-firo.yang@suse.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/sysctl.c | 73 ++++++++++++++++++++++++++++-------------------
+ 1 file changed, 44 insertions(+), 29 deletions(-)
+
+diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
+index c16c80963e55..e4af050aec1b 100644
+--- a/net/sctp/sysctl.c
++++ b/net/sctp/sysctl.c
+@@ -79,17 +79,18 @@ static struct ctl_table sctp_table[] = {
+       { /* sentinel */ }
+ };
++/* The following index defines are used in sctp_sysctl_net_register().
++ * If you add new items to the sctp_net_table, please ensure that
++ * the index values of these defines hold the same meaning indicated by
++ * their macro names when they appear in sctp_net_table.
++ */
++#define SCTP_RTO_MIN_IDX       0
++#define SCTP_RTO_MAX_IDX       1
++#define SCTP_PF_RETRANS_IDX    2
++#define SCTP_PS_RETRANS_IDX    3
++
+ static struct ctl_table sctp_net_table[] = {
+-      {
+-              .procname       = "rto_initial",
+-              .data           = &init_net.sctp.rto_initial,
+-              .maxlen         = sizeof(unsigned int),
+-              .mode           = 0644,
+-              .proc_handler   = proc_dointvec_minmax,
+-              .extra1         = SYSCTL_ONE,
+-              .extra2         = &timer_max
+-      },
+-      {
++      [SCTP_RTO_MIN_IDX] = {
+               .procname       = "rto_min",
+               .data           = &init_net.sctp.rto_min,
+               .maxlen         = sizeof(unsigned int),
+@@ -98,7 +99,7 @@ static struct ctl_table sctp_net_table[] = {
+               .extra1         = SYSCTL_ONE,
+               .extra2         = &init_net.sctp.rto_max
+       },
+-      {
++      [SCTP_RTO_MAX_IDX] =  {
+               .procname       = "rto_max",
+               .data           = &init_net.sctp.rto_max,
+               .maxlen         = sizeof(unsigned int),
+@@ -107,6 +108,33 @@ static struct ctl_table sctp_net_table[] = {
+               .extra1         = &init_net.sctp.rto_min,
+               .extra2         = &timer_max
+       },
++      [SCTP_PF_RETRANS_IDX] = {
++              .procname       = "pf_retrans",
++              .data           = &init_net.sctp.pf_retrans,
++              .maxlen         = sizeof(int),
++              .mode           = 0644,
++              .proc_handler   = proc_dointvec_minmax,
++              .extra1         = SYSCTL_ZERO,
++              .extra2         = &init_net.sctp.ps_retrans,
++      },
++      [SCTP_PS_RETRANS_IDX] = {
++              .procname       = "ps_retrans",
++              .data           = &init_net.sctp.ps_retrans,
++              .maxlen         = sizeof(int),
++              .mode           = 0644,
++              .proc_handler   = proc_dointvec_minmax,
++              .extra1         = &init_net.sctp.pf_retrans,
++              .extra2         = &ps_retrans_max,
++      },
++      {
++              .procname       = "rto_initial",
++              .data           = &init_net.sctp.rto_initial,
++              .maxlen         = sizeof(unsigned int),
++              .mode           = 0644,
++              .proc_handler   = proc_dointvec_minmax,
++              .extra1         = SYSCTL_ONE,
++              .extra2         = &timer_max
++      },
+       {
+               .procname       = "rto_alpha_exp_divisor",
+               .data           = &init_net.sctp.rto_alpha,
+@@ -202,24 +230,6 @@ static struct ctl_table sctp_net_table[] = {
+               .extra1         = SYSCTL_ONE,
+               .extra2         = SYSCTL_INT_MAX,
+       },
+-      {
+-              .procname       = "pf_retrans",
+-              .data           = &init_net.sctp.pf_retrans,
+-              .maxlen         = sizeof(int),
+-              .mode           = 0644,
+-              .proc_handler   = proc_dointvec_minmax,
+-              .extra1         = SYSCTL_ZERO,
+-              .extra2         = &init_net.sctp.ps_retrans,
+-      },
+-      {
+-              .procname       = "ps_retrans",
+-              .data           = &init_net.sctp.ps_retrans,
+-              .maxlen         = sizeof(int),
+-              .mode           = 0644,
+-              .proc_handler   = proc_dointvec_minmax,
+-              .extra1         = &init_net.sctp.pf_retrans,
+-              .extra2         = &ps_retrans_max,
+-      },
+       {
+               .procname       = "sndbuf_policy",
+               .data           = &init_net.sctp.sndbuf_policy,
+@@ -489,6 +499,11 @@ int sctp_sysctl_net_register(struct net *net)
+       for (i = 0; table[i].data; i++)
+               table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
++      table[SCTP_RTO_MIN_IDX].extra2 = &net->sctp.rto_max;
++      table[SCTP_RTO_MAX_IDX].extra1 = &net->sctp.rto_min;
++      table[SCTP_PF_RETRANS_IDX].extra2 = &net->sctp.ps_retrans;
++      table[SCTP_PS_RETRANS_IDX].extra1 = &net->sctp.pf_retrans;
++
+       net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
+       if (net->sctp.sysctl_header == NULL) {
+               kfree(table);
+-- 
+2.35.1
+
diff --git a/queue-5.10/selftests-devlink-fix-the-fd-redirect-in-dummy_repor.patch b/queue-5.10/selftests-devlink-fix-the-fd-redirect-in-dummy_repor.patch
new file mode 100644 (file)
index 0000000..b29fcfd
--- /dev/null
@@ -0,0 +1,45 @@
+From 51f1b52ae445f2898f5d59aa4ef2d6dc9418d8e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Dec 2022 18:01:01 -0800
+Subject: selftests: devlink: fix the fd redirect in dummy_reporter_test
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 2fc60e2ff972d3dca836bff0b08cbe503c4ca1ce ]
+
+$number + > bash means redirect FD $number, e.g. commonly
+used 2> redirects stderr (fd 2). The test uses 8192> to
+write the number 8192 to a file, this results in:
+
+  ./devlink.sh: line 499: 8192: Bad file descriptor
+
+Oddly the test also papers over this issue by checking
+for failure (expecting an error rather than success)
+so it passes, anyway.
+
+Fixes: ff18176ad806 ("selftests: Add a test of large binary to devlink health test")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/netdevsim/devlink.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+index 40909c254365..16d2de18591d 100755
+--- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
++++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+@@ -495,8 +495,8 @@ dummy_reporter_test()
+       check_reporter_info dummy healthy 3 3 10 true
+-      echo 8192> $DEBUGFS_DIR/health/binary_len
+-      check_fail $? "Failed set dummy reporter binary len to 8192"
++      echo 8192 > $DEBUGFS_DIR/health/binary_len
++      check_err $? "Failed set dummy reporter binary len to 8192"
+       local dump=$(devlink health dump show $DL_HANDLE reporter dummy -j)
+       check_err $? "Failed show dump of dummy reporter"
+-- 
+2.35.1
+
diff --git a/queue-5.10/selftests-efivarfs-add-checking-of-the-test-return-v.patch b/queue-5.10/selftests-efivarfs-add-checking-of-the-test-return-v.patch
new file mode 100644 (file)
index 0000000..906e923
--- /dev/null
@@ -0,0 +1,39 @@
+From 7d867c8189285b6c8c9db5258bc1952a1d7ecfaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 19:26:26 +0800
+Subject: selftests/efivarfs: Add checking of the test return value
+
+From: Zhao Gongyi <zhaogongyi@huawei.com>
+
+[ Upstream commit c93924267fe6f2b44af1849f714ae9cd8117a9cd ]
+
+Add checking of the test return value, otherwise it will report success
+forever for test_create_read().
+
+Fixes: dff6d2ae56d0 ("selftests/efivarfs: clean up test files from test_create*()")
+Signed-off-by: Zhao Gongyi <zhaogongyi@huawei.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/efivarfs/efivarfs.sh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/tools/testing/selftests/efivarfs/efivarfs.sh b/tools/testing/selftests/efivarfs/efivarfs.sh
+index a90f394f9aa9..d374878cc0ba 100755
+--- a/tools/testing/selftests/efivarfs/efivarfs.sh
++++ b/tools/testing/selftests/efivarfs/efivarfs.sh
+@@ -87,6 +87,11 @@ test_create_read()
+ {
+       local file=$efivarfs_mount/$FUNCNAME-$test_guid
+       ./create-read $file
++      if [ $? -ne 0 ]; then
++              echo "create and read $file failed"
++              file_cleanup $file
++              exit 1
++      fi
+       file_cleanup $file
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/selftests-ftrace-event_triggers-wait-longer-for-test.patch b/queue-5.10/selftests-ftrace-event_triggers-wait-longer-for-test.patch
new file mode 100644 (file)
index 0000000..ffc521a
--- /dev/null
@@ -0,0 +1,57 @@
+From cfb2c71c86164b6360261b314997f920a36df166 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 10:09:31 +0800
+Subject: selftests/ftrace: event_triggers: wait longer for test_event_enable
+
+From: Yipeng Zou <zouyipeng@huawei.com>
+
+[ Upstream commit a1d6cd88c8973cfb08ee85722488b1d6d5d16327 ]
+
+In some platform, the schedule event may came slowly, delay 100ms can't
+cover it.
+
+I was notice that on my board which running in low cpu_freq,and this
+selftests allways gose fail.
+
+So maybe we can check more times here to wait longer.
+
+Fixes: 43bb45da82f9 ("selftests: ftrace: Add a selftest to test event enable/disable func trigger")
+Signed-off-by: Yipeng Zou <zouyipeng@huawei.com>
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ftrace/test.d/ftrace/func_event_triggers.tc   | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
+index 3145b0f1835c..27a68bbe778b 100644
+--- a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
++++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
+@@ -38,11 +38,18 @@ cnt_trace() {
+ test_event_enabled() {
+     val=$1
++    check_times=10            # wait for 10 * SLEEP_TIME at most
+-    e=`cat $EVENT_ENABLE`
+-    if [ "$e" != $val ]; then
+-      fail "Expected $val but found $e"
+-    fi
++    while [ $check_times -ne 0 ]; do
++      e=`cat $EVENT_ENABLE`
++      if [ "$e" == $val ]; then
++          return 0
++      fi
++      sleep $SLEEP_TIME
++      check_times=$((check_times - 1))
++    done
++
++    fail "Expected $val but found $e"
+ }
+ run_enable_disable() {
+-- 
+2.35.1
+
diff --git a/queue-5.10/selftests-powerpc-fix-resource-leaks.patch b/queue-5.10/selftests-powerpc-fix-resource-leaks.patch
new file mode 100644 (file)
index 0000000..11aabea
--- /dev/null
@@ -0,0 +1,51 @@
+From c8addc06cb7997dc5004361b641b89bcfa3a8543 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 12:44:27 +0400
+Subject: selftests/powerpc: Fix resource leaks
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 8f4ab7da904ab7027ccd43ddb4f0094e932a5877 ]
+
+In check_all_cpu_dscr_defaults, opendir() opens the directory stream.
+Add missing closedir() in the error path to release it.
+
+In check_cpu_dscr_default, open() creates an open file descriptor.
+Add missing close() in the error path to release it.
+
+Fixes: ebd5858c904b ("selftests/powerpc: Add test for all DSCR sysfs interfaces")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20221205084429.570654-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
+index fbbdffdb2e5d..f20d1c166d1e 100644
+--- a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
++++ b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
+@@ -24,6 +24,7 @@ static int check_cpu_dscr_default(char *file, unsigned long val)
+       rc = read(fd, buf, sizeof(buf));
+       if (rc == -1) {
+               perror("read() failed");
++              close(fd);
+               return 1;
+       }
+       close(fd);
+@@ -65,8 +66,10 @@ static int check_all_cpu_dscr_defaults(unsigned long val)
+               if (access(file, F_OK))
+                       continue;
+-              if (check_cpu_dscr_default(file, val))
++              if (check_cpu_dscr_default(file, val)) {
++                      closedir(sysfs);
+                       return 1;
++              }
+       }
+       closedir(sysfs);
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/serial-altera_uart-fix-locking-in-polling-mode.patch b/queue-5.10/serial-altera_uart-fix-locking-in-polling-mode.patch
new file mode 100644 (file)
index 0000000..8485517
--- /dev/null
@@ -0,0 +1,51 @@
+From b3f9d8075f83eee30a703fce1d1177ea2d60eac5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 15:04:26 -0500
+Subject: serial: altera_uart: fix locking in polling mode
+
+From: Gabriel Somlo <gsomlo@gmail.com>
+
+[ Upstream commit 1307c5d33cce8a41dd77c2571e4df65a5b627feb ]
+
+Since altera_uart_interrupt() may also be called from
+a poll timer in "serving_softirq" context, use
+spin_[lock_irqsave|unlock_irqrestore] variants, which
+are appropriate for both softirq and hardware interrupt
+contexts.
+
+Fixes: 2f8b9c15cd88 ("altera_uart: Add support for polling mode (IRQ-less)")
+Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
+Link: https://lore.kernel.org/r/20221122200426.888349-1-gsomlo@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/altera_uart.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
+index 20c610440133..d91f76b1d353 100644
+--- a/drivers/tty/serial/altera_uart.c
++++ b/drivers/tty/serial/altera_uart.c
+@@ -280,16 +280,17 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data)
+ {
+       struct uart_port *port = data;
+       struct altera_uart *pp = container_of(port, struct altera_uart, port);
++      unsigned long flags;
+       unsigned int isr;
+       isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr;
+-      spin_lock(&port->lock);
++      spin_lock_irqsave(&port->lock, flags);
+       if (isr & ALTERA_UART_STATUS_RRDY_MSK)
+               altera_uart_rx_chars(port);
+       if (isr & ALTERA_UART_STATUS_TRDY_MSK)
+               altera_uart_tx_chars(port);
+-      spin_unlock(&port->lock);
++      spin_unlock_irqrestore(&port->lock, flags);
+       return IRQ_RETVAL(isr);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/serial-amba-pl011-avoid-sbsa-uart-accessing-dmacr-re.patch b/queue-5.10/serial-amba-pl011-avoid-sbsa-uart-accessing-dmacr-re.patch
new file mode 100644 (file)
index 0000000..f92ddbb
--- /dev/null
@@ -0,0 +1,93 @@
+From 0661751bc6a498fc145df4354b82cb4088bc7d7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 18:32:37 +0800
+Subject: serial: amba-pl011: avoid SBSA UART accessing DMACR register
+
+From: Jiamei Xie <jiamei.xie@arm.com>
+
+[ Upstream commit 94cdb9f33698478b0e7062586633c42c6158a786 ]
+
+Chapter "B Generic UART" in "ARM Server Base System Architecture" [1]
+documentation describes a generic UART interface. Such generic UART
+does not support DMA. In current code, sbsa_uart_pops and
+amba_pl011_pops share the same stop_rx operation, which will invoke
+pl011_dma_rx_stop, leading to an access of the DMACR register. This
+commit adds a using_rx_dma check in pl011_dma_rx_stop to avoid the
+access to DMACR register for SBSA UARTs which does not support DMA.
+
+When the kernel enables DMA engine with "CONFIG_DMA_ENGINE=y", Linux
+SBSA PL011 driver will access PL011 DMACR register in some functions.
+For most real SBSA Pl011 hardware implementations, the DMACR write
+behaviour will be ignored. So these DMACR operations will not cause
+obvious problems. But for some virtual SBSA PL011 hardware, like Xen
+virtual SBSA PL011 (vpl011) device, the behaviour might be different.
+Xen vpl011 emulation will inject a data abort to guest, when guest is
+accessing an unimplemented UART register. As Xen VPL011 is SBSA
+compatible, it will not implement DMACR register. So when Linux SBSA
+PL011 driver access DMACR register, it will get an unhandled data abort
+fault and the application will get a segmentation fault:
+Unhandled fault at 0xffffffc00944d048
+Mem abort info:
+  ESR = 0x96000000
+  EC = 0x25: DABT (current EL), IL = 32 bits
+  SET = 0, FnV = 0
+  EA = 0, S1PTW = 0
+  FSC = 0x00: ttbr address size fault
+Data abort info:
+  ISV = 0, ISS = 0x00000000
+  CM = 0, WnR = 0
+swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000020e2e000
+[ffffffc00944d048] pgd=100000003ffff803, p4d=100000003ffff803, pud=100000003ffff803, pmd=100000003fffa803, pte=006800009c090f13
+Internal error: ttbr address size fault: 96000000 [#1] PREEMPT SMP
+...
+Call trace:
+ pl011_stop_rx+0x70/0x80
+ tty_port_shutdown+0x7c/0xb4
+ tty_port_close+0x60/0xcc
+ uart_close+0x34/0x8c
+ tty_release+0x144/0x4c0
+ __fput+0x78/0x220
+ ____fput+0x1c/0x30
+ task_work_run+0x88/0xc0
+ do_notify_resume+0x8d0/0x123c
+ el0_svc+0xa8/0xc0
+ el0t_64_sync_handler+0xa4/0x130
+ el0t_64_sync+0x1a0/0x1a4
+Code: b9000083 b901f001 794038a0 8b000042 (b9000041)
+---[ end trace 83dd93df15c3216f ]---
+note: bootlogd[132] exited with preempt_count 1
+/etc/rcS.d/S07bootlogd: line 47: 132 Segmentation fault start-stop-daemon
+
+This has been discussed in the Xen community, and we think it should fix
+this in Linux. See [2] for more information.
+
+[1] https://developer.arm.com/documentation/den0094/c/?lang=en
+[2] https://lists.xenproject.org/archives/html/xen-devel/2022-11/msg00543.html
+
+Fixes: 0dd1e247fd39 (drivers: PL011: add support for the ARM SBSA generic UART)
+Signed-off-by: Jiamei Xie <jiamei.xie@arm.com>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Link: https://lore.kernel.org/r/20221117103237.86856-1-jiamei.xie@arm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/amba-pl011.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
+index 9900ee3f9068..2f7373fc7bb7 100644
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1048,6 +1048,9 @@ static void pl011_dma_rx_callback(void *data)
+  */
+ static inline void pl011_dma_rx_stop(struct uart_amba_port *uap)
+ {
++      if (!uap->using_rx_dma)
++              return;
++
+       /* FIXME.  Just disable the DMA enable */
+       uap->dmacr &= ~UART011_RXDMAE;
+       pl011_write(uap->dmacr, uap, REG_DMACR);
+-- 
+2.35.1
+
diff --git a/queue-5.10/serial-pch-fix-pci-device-refcount-leak-in-pch_reque.patch b/queue-5.10/serial-pch-fix-pci-device-refcount-leak-in-pch_reque.patch
new file mode 100644 (file)
index 0000000..1d5d6e3
--- /dev/null
@@ -0,0 +1,58 @@
+From f1126546beb14add2f64c452b252883c17e68f6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 19:45:59 +0800
+Subject: serial: pch: Fix PCI device refcount leak in pch_request_dma()
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit 8be3a7bf773700534a6e8f87f6ed2ed111254be5 ]
+
+As comment of pci_get_slot() says, it returns a pci_device with its
+refcount increased. The caller must decrement the reference count by
+calling pci_dev_put().
+
+Since 'dma_dev' is only used to filter the channel in filter(), we can
+call pci_dev_put() before exiting from pch_request_dma(). Add the
+missing pci_dev_put() for the normal and error path.
+
+Fixes: 3c6a483275f4 ("Serial: EG20T: add PCH_UART driver")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Link: https://lore.kernel.org/r/20221122114559.27692-1-wangxiongfeng2@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/pch_uart.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
+index 351ad0b02029..fa2061f1cf3d 100644
+--- a/drivers/tty/serial/pch_uart.c
++++ b/drivers/tty/serial/pch_uart.c
+@@ -711,6 +711,7 @@ static void pch_request_dma(struct uart_port *port)
+       if (!chan) {
+               dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Tx)\n",
+                       __func__);
++              pci_dev_put(dma_dev);
+               return;
+       }
+       priv->chan_tx = chan;
+@@ -727,6 +728,7 @@ static void pch_request_dma(struct uart_port *port)
+                       __func__);
+               dma_release_channel(priv->chan_tx);
+               priv->chan_tx = NULL;
++              pci_dev_put(dma_dev);
+               return;
+       }
+@@ -734,6 +736,8 @@ static void pch_request_dma(struct uart_port *port)
+       priv->rx_buf_virt = dma_alloc_coherent(port->dev, port->fifosize,
+                                   &priv->rx_buf_dma, GFP_KERNEL);
+       priv->chan_rx = chan;
++
++      pci_dev_put(dma_dev);
+ }
+ static void pch_dma_rx_complete(void *arg)
+-- 
+2.35.1
+
diff --git a/queue-5.10/serial-pl011-do-not-clear-rx-fifo-rx-interrupt-in-un.patch b/queue-5.10/serial-pl011-do-not-clear-rx-fifo-rx-interrupt-in-un.patch
new file mode 100644 (file)
index 0000000..28c0722
--- /dev/null
@@ -0,0 +1,52 @@
+From e1948ad8d618642048f4a7237b2048bcabd0cb77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 10:01:08 +0800
+Subject: serial: pl011: Do not clear RX FIFO & RX interrupt in unthrottle.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: delisun <delisun@pateo.com.cn>
+
+[ Upstream commit 032d5a71ed378ffc6a2d41a187d8488a4f9fe415 ]
+
+Clearing the RX FIFO will cause data loss.
+Copy the pl011_enabl_interrupts implementation, and remove the clear
+interrupt and FIFO part of the code.
+
+Fixes: 211565b10099 ("serial: pl011: UPSTAT_AUTORTS requires .throttle/unthrottle")
+Signed-off-by: delisun <delisun@pateo.com.cn>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://lore.kernel.org/r/20221110020108.7700-1-delisun@pateo.com.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/amba-pl011.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
+index 2f7373fc7bb7..348d4b2a391a 100644
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1760,8 +1760,17 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
+ static void pl011_unthrottle_rx(struct uart_port *port)
+ {
+       struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port);
++      unsigned long flags;
+-      pl011_enable_interrupts(uap);
++      spin_lock_irqsave(&uap->port.lock, flags);
++
++      uap->im = UART011_RTIM;
++      if (!pl011_dma_rx_running(uap))
++              uap->im |= UART011_RXIM;
++
++      pl011_write(uap->im, uap, REG_IMSC);
++
++      spin_unlock_irqrestore(&uap->port.lock, flags);
+ }
+ static int pl011_startup(struct uart_port *port)
+-- 
+2.35.1
+
diff --git a/queue-5.10/serial-sunsab-fix-error-handling-in-sunsab_init.patch b/queue-5.10/serial-sunsab-fix-error-handling-in-sunsab_init.patch
new file mode 100644 (file)
index 0000000..c7a56ab
--- /dev/null
@@ -0,0 +1,46 @@
+From 68cb56f4d6705dacbe460b9af14e2f843dc977d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 06:12:12 +0000
+Subject: serial: sunsab: Fix error handling in sunsab_init()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 1a6ec673fb627c26e2267ca0a03849f91dbd9b40 ]
+
+The sunsab_init() returns the platform_driver_register() directly without
+checking its return value, if platform_driver_register() failed, the
+allocated sunsab_ports is leaked.
+Fix by free sunsab_ports and set it to NULL when platform_driver_register()
+failed.
+
+Fixes: c4d37215a824 ("[SERIAL] sunsab: Convert to of_driver framework.")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Link: https://lore.kernel.org/r/20221123061212.52593-1-yuancan@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sunsab.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c
+index bab551f46963..451c7233623f 100644
+--- a/drivers/tty/serial/sunsab.c
++++ b/drivers/tty/serial/sunsab.c
+@@ -1137,7 +1137,13 @@ static int __init sunsab_init(void)
+               }
+       }
+-      return platform_driver_register(&sab_driver);
++      err = platform_driver_register(&sab_driver);
++      if (err) {
++              kfree(sunsab_ports);
++              sunsab_ports = NULL;
++      }
++
++      return err;
+ }
+ static void __exit sunsab_exit(void)
+-- 
+2.35.1
+
diff --git a/queue-5.10/serial-tegra-read-dma-status-before-terminating.patch b/queue-5.10/serial-tegra-read-dma-status-before-terminating.patch
new file mode 100644 (file)
index 0000000..54d7b20
--- /dev/null
@@ -0,0 +1,60 @@
+From 52e86ae317bd0398633ac8b16bebb197033b5921 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 20:28:06 +0530
+Subject: serial: tegra: Read DMA status before terminating
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kartik <kkartik@nvidia.com>
+
+[ Upstream commit 109a951a9f1fd8a34ebd1896cbbd5d5cede880a7 ]
+
+Read the DMA status before terminating the DMA, as doing so deletes
+the DMA desc.
+
+Also, to get the correct transfer status information, pause the DMA
+using dmaengine_pause() before reading the DMA status.
+
+Fixes: e9ea096dd225 ("serial: tegra: add serial driver")
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Acked-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Kartik <kkartik@nvidia.com>
+Link: https://lore.kernel.org/r/1666105086-17326-1-git-send-email-kkartik@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/serial-tegra.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c
+index cda71802b698..62377c831894 100644
+--- a/drivers/tty/serial/serial-tegra.c
++++ b/drivers/tty/serial/serial-tegra.c
+@@ -614,8 +614,9 @@ static void tegra_uart_stop_tx(struct uart_port *u)
+       if (tup->tx_in_progress != TEGRA_UART_TX_DMA)
+               return;
+-      dmaengine_terminate_all(tup->tx_dma_chan);
++      dmaengine_pause(tup->tx_dma_chan);
+       dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state);
++      dmaengine_terminate_all(tup->tx_dma_chan);
+       count = tup->tx_bytes_requested - state.residue;
+       async_tx_ack(tup->tx_dma_desc);
+       uart_xmit_advance(&tup->uport, count);
+@@ -758,8 +759,9 @@ static void tegra_uart_terminate_rx_dma(struct tegra_uart_port *tup)
+               return;
+       }
+-      dmaengine_terminate_all(tup->rx_dma_chan);
++      dmaengine_pause(tup->rx_dma_chan);
+       dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state);
++      dmaengine_terminate_all(tup->rx_dma_chan);
+       tegra_uart_rx_buffer_push(tup, state.residue);
+       tup->rx_dma_active = false;
+-- 
+2.35.1
+
diff --git a/queue-5.10/series b/queue-5.10/series
new file mode 100644 (file)
index 0000000..9bbe7e5
--- /dev/null
@@ -0,0 +1,545 @@
+usb-musb-remove-extra-check-in-musb_gadget_vbus_draw.patch
+arm64-dts-qcom-ipq6018-cp01-c1-use-blspi1-pins.patch
+arm64-dts-qcom-msm8996-fix-gpu-opp-table.patch
+arm-dts-qcom-apq8064-fix-coresight-compatible.patch
+arm64-dts-qcom-sdm630-fix-uart1-pin-bias.patch
+arm64-dts-qcom-sdm845-cheza-fix-ap-suspend-pin-bias.patch
+arm64-dts-qcom-msm8916-drop-mss-fallback-compatible.patch
+objtool-kcsan-add-volatile-read-write-instrumentatio.patch
+arm-dts-stm32-drop-stm32mp15xc.dtsi-from-avenger96.patch
+arm-dts-stm32-fix-av96-wlan-regulator-gpio-property.patch
+drivers-soc-ti-knav_qmss_queue-mark-knav_acc_firmwar.patch
+soc-qcom-llcc-make-irq-truly-optional.patch
+soc-qcom-apr-make-code-more-reuseable.patch
+soc-qcom-apr-add-check-for-idr_alloc-and-of_property.patch
+arm-dts-spear600-fix-clcd-interrupt.patch
+soc-ti-knav_qmss_queue-use-pm_runtime_resume_and_get.patch
+soc-ti-knav_qmss_queue-fix-pm-disable-depth-imbalanc.patch
+soc-ti-smartreflex-fix-pm-disable-depth-imbalance-in.patch
+perf-arm_dsu-fix-hotplug-callback-leak-in-dsu_pmu_in.patch
+perf-smmuv3-fix-hotplug-callback-leak-in-arm_smmu_pm.patch
+arm64-dts-ti-k3-am65-main-drop-dma-coherent-in-crypt.patch
+arm64-dts-ti-k3-j721e-main-drop-dma-coherent-in-cryp.patch
+arm64-dts-mt2712e-fix-unit_address_vs_reg-warning-fo.patch
+arm64-dts-mt2712e-fix-unit-address-for-pinctrl-node.patch
+arm64-dts-mt2712-evb-fix-vproc-fixed-regulators-unit.patch
+arm64-dts-mt2712-evb-fix-usb-vbus-regulators-unit-na.patch
+arm64-dts-mediatek-pumpkin-common-fix-devicetree-war.patch
+arm64-dts-mediatek-mt6797-fix-26m-oscillator-unit-na.patch
+arm-dts-dove-fix-assigned-addresses-for-every-pcie-r.patch
+arm-dts-armada-370-fix-assigned-addresses-for-every-.patch
+arm-dts-armada-xp-fix-assigned-addresses-for-every-p.patch
+arm-dts-armada-375-fix-assigned-addresses-for-every-.patch
+arm-dts-armada-38x-fix-assigned-addresses-for-every-.patch
+arm-dts-armada-39x-fix-assigned-addresses-for-every-.patch
+arm-dts-turris-omnia-add-ethernet-aliases.patch
+arm-dts-turris-omnia-add-switch-port-6-node.patch
+arm-dts-armada-38x-fix-compatible-string-for-gpios.patch
+arm-dts-armada-39x-fix-compatible-string-for-gpios.patch
+arm64-dts-armada-3720-turris-mox-add-missing-interru.patch
+pstore-ram-fix-error-return-code-in-ramoops_probe.patch
+arm-mmp-fix-timer_read-delay.patch
+pstore-avoid-kcore-oops-by-vmap-ing-with-vm_ioremap.patch
+tpm-tpm_ftpm_tee-fix-error-handling-in-ftpm_mod_init.patch
+tpm-tpm_crb-fix-error-message-in-__crb_relinquish_lo.patch
+sched-fair-cleanup-task_util-and-capacity-type.patch
+sched-uclamp-fix-relationship-between-uclamp-and-mig.patch
+cpuidle-dt-return-the-correct-numbers-of-parsed-idle.patch
+alpha-fix-syscall-entry-in-audut_syscall-case.patch
+pm-hibernate-fix-mistake-in-kerneldoc-comment.patch
+fs-don-t-audit-the-capability-check-in-simple_xattr_.patch
+cpufreq-qcom-hw-fix-memory-leak-in-qcom_cpufreq_hw_r.patch
+selftests-ftrace-event_triggers-wait-longer-for-test.patch
+perf-fix-possible-memleak-in-pmu_dev_alloc.patch
+lib-debugobjects-fix-stat-count-and-optimize-debug_o.patch
+platform-x86-huawei-wmi-fix-return-value-calculation.patch
+timerqueue-use-rb_entry_safe-in-timerqueue_getnext.patch
+proc-fixup-uptime-selftest.patch
+lib-fonts-fix-undefined-behavior-in-bit-shift-for-ge.patch
+ocfs2-fix-memory-leak-in-ocfs2_stack_glue_init.patch
+mips-vpe-mt-fix-possible-memory-leak-while-module-ex.patch
+mips-vpe-cmp-fix-possible-memory-leak-while-module-e.patch
+selftests-efivarfs-add-checking-of-the-test-return-v.patch
+pnp-fix-name-memory-leak-in-pnp_alloc_dev.patch
+perf-x86-intel-uncore-fix-reference-count-leak-in-hs.patch
+perf-x86-intel-uncore-fix-reference-count-leak-in-sn.patch
+perf-x86-intel-uncore-fix-reference-count-leak-in-__.patch
+platform-chrome-cros_usbpd_notify-fix-error-handling.patch
+irqchip-gic-pm-use-pm_runtime_resume_and_get-in-gic_.patch
+edac-i10nm-fix-refcount-leak-in-pci_get_dev_wrapper.patch
+nfsd-don-t-call-nfsd_file_put-from-client-states-seq.patch
+genirq-irqdesc-don-t-try-to-remove-non-existing-sysf.patch
+cpufreq-amd_freq_sensitivity-add-missing-pci_dev_put.patch
+libfs-add-define_simple_attribute_signed-for-signed-.patch
+lib-notifier-error-inject-fix-error-when-writing-err.patch
+docs-fault-injection-fix-non-working-usage-of-negati.patch
+debugfs-fix-error-when-writing-negative-value-to-ato.patch
+ocfs2-ocfs2_mount_volume-does-cleanup-job-before-ret.patch
+ocfs2-rewrite-error-handling-of-ocfs2_fill_super.patch
+ocfs2-fix-memory-leak-in-ocfs2_mount_volume.patch
+rapidio-fix-possible-name-leaks-when-rio_add_device-.patch
+rapidio-rio-fix-possible-name-leak-in-rio_register_m.patch
+clocksource-drivers-sh_cmt-make-sure-channel-clock-s.patch
+clocksource-drivers-sh_cmt-access-registers-accordin.patch
+futex-move-to-kernel-futex.patch
+futex-resend-potentially-swallowed-owner-death-notif.patch
+cpu-hotplug-make-target_store-a-nop-when-target-stat.patch
+clocksource-drivers-timer-ti-dm-fix-missing-clk_disa.patch
+acpica-fix-use-after-free-in-acpi_ut_copy_ipackage_t.patch
+uprobes-x86-allow-to-probe-a-nop-instruction-with-0x.patch
+x86-xen-fix-memory-leak-in-xen_smp_intr_init-_pv.patch
+x86-xen-fix-memory-leak-in-xen_init_lock_cpu.patch
+xen-privcmd-fix-a-possible-warning-in-privcmd_ioctl_.patch
+pm-runtime-improve-path-in-rpm_idle-when-no-callback.patch
+pm-runtime-do-not-call-__rpm_callback-from-rpm_idle.patch
+platform-x86-mxm-wmi-fix-memleak-in-mxm_wmi_call_mx-.patch
+platform-x86-intel_scu_ipc-fix-possible-name-leak-in.patch
+mips-bcm63xx-add-check-for-null-for-clk-in-clk_enabl.patch
+mips-octeon-warn-only-once-if-deprecated-link-status.patch
+fs-sysv-fix-sysv_nblocks-returns-wrong-value.patch
+rapidio-fix-possible-uaf-when-kfifo_alloc-fails.patch
+eventfd-change-int-to-__u64-in-eventfd_signal-ifndef.patch
+relay-fix-type-mismatch-when-allocating-memory-in-re.patch
+hfs-fix-oob-write-in-hfs_asc2mac.patch
+rapidio-devices-fix-missing-put_device-in-mport_cdev.patch
+wifi-ath9k-hif_usb-fix-memory-leak-of-urbs-in-ath9k_.patch
+wifi-ath9k-hif_usb-fix-use-after-free-in-ath9k_hif_u.patch
+wifi-rtl8xxxu-fix-reading-the-vendor-of-combo-chips.patch
+drm-bridge-adv7533-remove-dynamic-lane-switching-fro.patch
+libbpf-fix-use-after-free-in-btf_dump_name_dups.patch
+libbpf-fix-null-pointer-dereference-in-find_prog_by_.patch
+pata_ipx4xx_cf-fix-unsigned-comparison-with-less-tha.patch
+powerpc-dts-t208x-mark-mac1-and-mac2-as-10g.patch
+media-coda-jpeg-add-check-for-kmalloc.patch
+media-i2c-ad5820-fix-error-path.patch
+venus-pm_helpers-fix-error-check-in-vcodec_domains_g.patch
+media-exynos4-is-use-v4l2_async_notifier_add_fwnode_.patch
+media-exynos4-is-don-t-rely-on-the-v4l2_async_subdev.patch
+can-kvaser_usb-do-not-increase-tx-statistics-when-se.patch
+can-kvaser_usb-kvaser_usb_leaf-get-capabilities-from.patch
+can-kvaser_usb-kvaser_usb_leaf-rename-leaf-usbcan-_c.patch
+can-kvaser_usb-kvaser_usb_leaf-handle-cmd_error_even.patch
+can-kvaser_usb_leaf-set-warning-state-even-without-b.patch
+can-kvaser_usb_leaf-fix-improved-state-not-being-rep.patch
+can-kvaser_usb_leaf-fix-wrong-can-state-after-stoppi.patch
+can-kvaser_usb_leaf-fix-bogus-restart-events.patch
+can-kvaser_usb-add-struct-kvaser_usb_busparams.patch
+can-kvaser_usb-compare-requested-bittiming-parameter.patch
+drm-rockchip-lvds-fix-pm-usage-counter-unbalance-in-.patch
+clk-renesas-r9a06g032-repair-grave-increment-error.patch
+spi-update-reference-to-struct-spi_controller.patch
+drm-panel-panel-sitronix-st7701-remove-panel-on-dsi-.patch
+ima-fix-fall-through-warnings-for-clang.patch
+ima-handle-estale-returned-by-ima_filter_rule_match.patch
+drm-msm-hdmi-switch-to-drm_bridge_connector.patch
+drm-msm-hdmi-drop-unused-gpio-support.patch
+bpf-fix-slot-type-check-in-check_stack_write_var_off.patch
+media-vivid-fix-compose-size-exceed-boundary.patch
+media-platform-exynos4-is-fix-return-value-check-in-.patch
+bpf-propagate-precision-in-alu-alu64-operations.patch
+bpf-check-the-other-end-of-slot_type-for-stack_spill.patch
+bpf-propagate-precision-across-all-frames-not-just-t.patch
+clk-qcom-gcc-sm8250-use-retention-mode-for-usb-gdscs.patch
+mtd-fix-device-name-leak-when-register-device-failed.patch
+input-joystick-fix-kconfig-warning-for-joystick_adc.patch
+wifi-rsi-fix-handling-of-802.3-eapol-frames-sent-via.patch
+media-camss-clean-up-received-buffers-on-failed-star.patch
+net-proc-provide-proc_fs-n-fallback-for-proc_create_.patch
+rxrpc-fix-ack.buffersize-to-be-0-when-generating-an-.patch
+drm-radeon-add-the-missed-acpi_put_table-to-fix-memo.patch
+drm-mediatek-modify-dpi-power-on-off-sequence.patch
+asoc-pxa-fix-null-pointer-dereference-in-filter.patch
+regulator-core-fix-unbalanced-of-node-refcount-in-re.patch
+amdgpu-pm-prevent-array-underflow-in-vega20_odn_edit.patch
+drm-fourcc-add-packed-10bit-yuv-4-2-0-format.patch
+drm-fourcc-fix-vsub-hsub-for-q410-and-q401.patch
+integrity-fix-memory-leakage-in-keyring-allocation-e.patch
+ima-fix-misuse-of-dereference-of-pointer-in-template.patch
+wifi-ath10k-fix-return-value-in-ath10k_pci_init.patch
+mtd-lpddr2_nvm-fix-possible-null-ptr-deref.patch
+input-elants_i2c-properly-handle-the-reset-gpio-when.patch
+media-vidtv-fix-use-after-free-in-vidtv_bridge_dvb_i.patch
+media-solo6x10-fix-possible-memory-leak-in-solo_sysf.patch
+media-platform-exynos4-is-fix-error-handling-in-fimc.patch
+media-videobuf-dma-contig-use-dma_mmap_coherent.patch
+inet-add-read_once-sk-sk_bound_dev_if-in-inet_csk_bi.patch
+bpf-move-skb-len-0-checks-into-__bpf_redirect.patch
+hid-hid-sensor-custom-set-fixed-size-for-custom-attr.patch
+alsa-pcm-fix-undefined-behavior-in-bit-shift-for-snd.patch
+alsa-seq-fix-undefined-behavior-in-bit-shift-for-snd.patch
+regulator-core-use-kfree_const-to-free-space-conditi.patch
+clk-rockchip-fix-memory-leak-in-rockchip_clk_registe.patch
+drm-amdgpu-fix-pci-device-refcount-leak.patch
+bonding-fix-link-recovery-in-mode-2-when-updelay-is-.patch
+mtd-maps-pxa2xx-flash-fix-memory-leak-in-probe.patch
+drbd-fix-an-invalid-memory-access-caused-by-incorrec.patch
+asoc-qcom-add-checks-for-devm_kcalloc.patch
+media-vimc-fix-wrong-function-called-when-vimc_init-.patch
+media-imon-fix-a-race-condition-in-send_packet.patch
+clk-imx-replace-osc_hdmi-with-dummy.patch
+pinctrl-pinconf-generic-add-missing-of_node_put.patch
+media-dvb-core-fix-ignored-return-value-in-dvb_regis.patch
+media-dvb-usb-az6027-fix-null-ptr-deref-in-az6027_i2.patch
+media-s5p-mfc-add-variant-data-for-mfc-v7-hardware-f.patch
+drm-tegra-add-missing-clk_disable_unprepare-in-tegra.patch
+asoc-dt-bindings-wcd9335-fix-reset-line-polarity-in-.patch
+asoc-mediatek-mtk-btcvsd-add-checks-for-write-and-re.patch
+nfsv4.2-clear-fattr4_word2_security_label-when-done-.patch
+nfsv4.2-fix-a-memory-stomp-in-decode_attr_security_l.patch
+nfsv4.2-fix-initialisation-of-struct-nfs4_label.patch
+nfsv4-fix-a-deadlock-between-nfs4_open_recover_helpe.patch
+nfs-fix-an-oops-in-nfs_d_automount.patch
+alsa-asihpi-fix-missing-pci_disable_device.patch
+wifi-iwlwifi-mvm-fix-double-free-on-tx-path.patch
+asoc-mediatek-mt8173-fix-debugfs-registration-for-co.patch
+asoc-mediatek-mt8173-enable-irq-when-pdata-is-ready.patch
+drm-amd-pm-smu11-baco-is-supported-when-it-s-in-baco.patch
+drm-radeon-fix-pci-device-refcount-leak-in-radeon_at.patch
+drm-amdgpu-fix-pci-device-refcount-leak-in-amdgpu_at.patch
+asoc-pcm512x-fix-pm-disable-depth-imbalance-in-pcm51.patch
+netfilter-conntrack-set-icmpv6-redirects-as-related.patch
+bpf-sockmap-fix-repeated-calls-to-sock_put-when-msg-.patch
+bpf-sockmap-fix-data-loss-caused-by-using-apply_byte.patch
+bonding-uninitialized-variable-in-bond_miimon_inspec.patch
+spi-spidev-mask-spi_cs_high-in-spi_ioc_rd_mode.patch
+wifi-mac80211-fix-memory-leak-in-ieee80211_if_add.patch
+wifi-cfg80211-fix-not-unregister-reg_pdev-when-load_.patch
+wifi-mt76-fix-coverity-overrun-call-in-mt76_get_txpo.patch
+regulator-core-fix-module-refcount-leak-in-set_suppl.patch
+clk-qcom-clk-krait-fix-wrong-div2-functions.patch
+hsr-add-a-rcu-read-lock-to-hsr_forward_skb.patch
+net-hsr-generate-supervision-frame-without-hsr-prp-t.patch
+hsr-disable-netpoll.patch
+hsr-synchronize-sending-frames-to-have-always-increm.patch
+hsr-synchronize-sequence-number-updates.patch
+configfs-fix-possible-memory-leak-in-configfs_create.patch
+regulator-core-fix-resource-leak-in-regulator_regist.patch
+hwmon-jc42-convert-register-access-and-caching-to-re.patch
+hwmon-jc42-restore-the-min-max-critical-temperatures.patch
+bpf-sockmap-fix-race-in-sock_map_free.patch
+alsa-pcm-set-missing-stop_operating-flag-at-undoing-.patch
+media-saa7164-fix-missing-pci_disable_device.patch
+alsa-mts64-fix-possible-null-ptr-defer-in-snd_mts64_.patch
+xprtrdma-fix-regbuf-data-not-freed-in-rpcrdma_req_cr.patch
+sunrpc-fix-missing-release-socket-in-rpc_sockname.patch
+nfsv4.x-fail-client-initialisation-if-state-manager-.patch
+mmc-alcor-fix-return-value-check-of-mmc_add_host.patch
+mmc-moxart-fix-return-value-check-of-mmc_add_host.patch
+mmc-mxcmmc-fix-return-value-check-of-mmc_add_host.patch
+mmc-pxamci-fix-return-value-check-of-mmc_add_host.patch
+mmc-rtsx_usb_sdmmc-fix-return-value-check-of-mmc_add.patch
+mmc-toshsd-fix-return-value-check-of-mmc_add_host.patch
+mmc-vub300-fix-return-value-check-of-mmc_add_host.patch
+mmc-wmt-sdmmc-fix-return-value-check-of-mmc_add_host.patch
+mmc-atmel-mci-fix-return-value-check-of-mmc_add_host.patch
+mmc-omap_hsmmc-fix-return-value-check-of-mmc_add_hos.patch
+mmc-meson-gx-fix-return-value-check-of-mmc_add_host.patch
+mmc-via-sdmmc-fix-return-value-check-of-mmc_add_host.patch
+mmc-wbsd-fix-return-value-check-of-mmc_add_host.patch
+mmc-mmci-fix-return-value-check-of-mmc_add_host.patch
+media-c8sectpfe-add-of_node_put-when-breaking-out-of.patch
+media-coda-add-check-for-dcoda_iram_alloc.patch
+media-coda-add-check-for-kmalloc.patch
+clk-samsung-fix-memory-leak-in-_samsung_clk_register.patch
+spi-spi-gpio-don-t-set-mosi-as-an-input-if-not-3wire.patch
+wifi-rtl8xxxu-add-__packed-to-struct-rtl8723bu_c2h.patch
+wifi-rtl8xxxu-fix-the-channel-width-reporting.patch
+wifi-brcmfmac-fix-error-return-code-in-brcmf_sdio_do.patch
+blktrace-fix-output-non-blktrace-event-when-blk_clas.patch
+clk-socfpga-clk-pll-remove-unused-variable-rc.patch
+clk-socfpga-use-clk_hw_register-for-a5-c5.patch
+clk-socfpga-fix-memory-leak-in-socfpga_gate_init.patch
+net-vmw_vsock-vmci-check-memcpy_from_msg.patch
+net-defxx-fix-missing-err-handling-in-dfx_init.patch
+net-stmmac-selftests-fix-potential-memleak-in-stmmac.patch
+drivers-net-qlcnic-fix-potential-memory-leak-in-qlcn.patch
+of-overlay-fix-null-pointer-dereferencing-in-find_du.patch
+ethernet-s2io-don-t-call-dev_kfree_skb-under-spin_lo.patch
+net-farsync-fix-kmemleak-when-rmmods-farsync.patch
+net-tunnel-wait-until-all-sk_user_data-reader-finish.patch
+net-apple-mace-don-t-call-dev_kfree_skb-under-spin_l.patch
+net-apple-bmac-don-t-call-dev_kfree_skb-under-spin_l.patch
+net-emaclite-don-t-call-dev_kfree_skb-under-spin_loc.patch
+net-ethernet-dnet-don-t-call-dev_kfree_skb-under-spi.patch
+hamradio-don-t-call-dev_kfree_skb-under-spin_lock_ir.patch
+net-amd-lance-don-t-call-dev_kfree_skb-under-spin_lo.patch
+net-amd-xgbe-fix-logic-around-active-and-passive-cab.patch
+net-amd-xgbe-check-only-the-minimum-speed-for-active.patch
+can-tcan4x5x-remove-invalid-write-in-clear_interrupt.patch
+net-lan9303-fix-read-error-execution-path.patch
+ntb_netdev-use-dev_kfree_skb_any-in-interrupt-contex.patch
+sctp-sysctl-make-extra-pointers-netns-aware.patch
+bluetooth-btusb-don-t-call-kfree_skb-under-spin_lock.patch
+bluetooth-hci_qca-don-t-call-kfree_skb-under-spin_lo.patch
+bluetooth-hci_ll-don-t-call-kfree_skb-under-spin_loc.patch
+bluetooth-hci_h5-don-t-call-kfree_skb-under-spin_loc.patch
+bluetooth-hci_bcsp-don-t-call-kfree_skb-under-spin_l.patch
+bluetooth-hci_core-don-t-call-kfree_skb-under-spin_l.patch
+bluetooth-rfcomm-don-t-call-kfree_skb-under-spin_loc.patch
+stmmac-fix-potential-division-by-0.patch
+apparmor-fix-a-memleak-in-multi_transaction_new.patch
+apparmor-fix-lockdep-warning-when-removing-a-namespa.patch
+apparmor-fix-abi-check-to-include-v8-abi.patch
+crypto-sun8i-ss-use-dma_addr-instead-u32.patch
+crypto-nitrox-avoid-double-free-on-error-path-in-nit.patch
+scsi-core-fix-a-race-between-scsi_done-and-scsi_time.patch
+apparmor-use-pointer-to-struct-aa_label-for-lbs_cred.patch
+pci-dwc-fix-n_fts-array-overrun.patch
+rdma-core-fix-order-of-nldev_exit-call.patch
+pci-pci-epf-test-register-notifier-if-only-core_init.patch
+f2fs-fix-the-race-condition-of-resize-flag-between-r.patch
+crypto-rockchip-do-not-do-custom-power-management.patch
+crypto-rockchip-do-not-store-mode-globally.patch
+crypto-rockchip-add-fallback-for-cipher.patch
+crypto-rockchip-add-fallback-for-ahash.patch
+crypto-rockchip-better-handle-cipher-key.patch
+crypto-rockchip-remove-non-aligned-handling.patch
+crypto-rockchip-delete-unneeded-variable-initializat.patch
+crypto-rockchip-rework-by-using-crypto_engine.patch
+apparmor-fix-memleak-in-alloc_ns.patch
+f2fs-fix-normal-discard-process.patch
+rdma-siw-fix-immediate-work-request-flush-to-complet.patch
+rdma-nldev-return-eagain-if-the-cm_id-isn-t-from-exp.patch
+rdma-siw-set-defined-status-for-work-completion-with.patch
+scsi-scsi_debug-fix-a-warning-in-resp_write_scat.patch
+crypto-ccree-remove-debugfs-when-platform_driver_reg.patch
+crypto-cryptd-use-request-context-instead-of-stack-f.patch
+crypto-hisilicon-qm-add-missing-pci_dev_put-in-q_num.patch
+rdma-hns-repacing-dseg_len-by-macros-in-fill_ext_sge.patch
+rdma-hns-fix-ext_sge-num-error-when-post-send.patch
+pci-check-for-alloc-failure-in-pci_request_irq.patch
+rdma-hfi-decrease-pci-device-reference-count-in-erro.patch
+crypto-ccree-make-cc_debugfs_global_fini-available-f.patch
+rdma-hns-fix-memory-leak-in-hns_roce_alloc_mr.patch
+rdma-rxe-fix-null-ptr-deref-in-rxe_qp_do_cleanup-whe.patch
+scsi-hpsa-fix-possible-memory-leak-in-hpsa_init_one.patch
+crypto-tcrypt-fix-multibuffer-skcipher-speed-test-me.patch
+padata-always-leave-bhs-disabled-when-running-parall.patch
+padata-fix-list-iterator-in-padata_do_serial.patch
+scsi-mpt3sas-fix-possible-resource-leaks-in-mpt3sas_.patch
+scsi-hpsa-fix-error-handling-in-hpsa_add_sas_host.patch
+scsi-hpsa-fix-possible-memory-leak-in-hpsa_add_sas_d.patch
+scsi-scsi_debug-fix-a-warning-in-resp_verify.patch
+scsi-scsi_debug-fix-a-warning-in-resp_report_zones.patch
+scsi-fcoe-fix-possible-name-leak-when-device_registe.patch
+scsi-scsi_debug-fix-possible-name-leak-in-sdebug_add.patch
+scsi-ipr-fix-warning-in-ipr_init.patch
+scsi-fcoe-fix-transport-not-deattached-when-fcoe_if_.patch
+scsi-snic-fix-possible-uaf-in-snic_tgt_create.patch
+rdma-nldev-add-checks-for-nla_nest_start-in-fill_sta.patch
+f2fs-avoid-victim-selection-from-previous-victim-sec.patch
+rdma-nldev-fix-failure-to-send-large-messages.patch
+crypto-amlogic-remove-kcalloc-without-check.patch
+crypto-omap-sham-use-pm_runtime_resume_and_get-in-om.patch
+riscv-mm-add-arch-hook-arch_clear_hugepage_flags.patch
+rdma-hfi1-fix-error-return-code-in-parse_platform_co.patch
+rdma-srp-fix-error-return-code-in-srp_parse_options.patch
+orangefs-fix-sysfs-not-cleanup-when-dev-init-failed.patch
+rdma-hns-fix-pbl-page-mtr-find.patch
+rdma-hns-fix-page-size-cap-from-firmware.patch
+crypto-img-hash-fix-variable-dereferenced-before-che.patch
+hwrng-amd-fix-pci-device-refcount-leak.patch
+hwrng-geode-fix-pci-device-refcount-leak.patch
+ib-ipoib-fix-queue-count-inconsistency-for-pkey-chil.patch
+drivers-dio-fix-possible-memory-leak-in-dio_init.patch
+serial-tegra-read-dma-status-before-terminating.patch
+class-fix-possible-memory-leak-in-__class_register.patch
+vfio-platform-do-not-pass-return-buffer-to-acpi-_rst.patch
+uio-uio_dmem_genirq-fix-missing-unlock-in-irq-config.patch
+uio-uio_dmem_genirq-fix-deadlock-between-irq-config-.patch
+usb-fotg210-udc-fix-ages-old-endianness-issues.patch
+staging-vme_user-fix-possible-uaf-in-tsi148_dma_list.patch
+usb-typec-check-for-ops-exit-instead-of-ops-enter-in.patch
+usb-typec-tcpci-fix-of-node-refcount-leak-in-tcpci_r.patch
+usb-typec-tipd-fix-spurious-fwnode_handle_put-in-err.patch
+serial-amba-pl011-avoid-sbsa-uart-accessing-dmacr-re.patch
+serial-pl011-do-not-clear-rx-fifo-rx-interrupt-in-un.patch
+serial-pch-fix-pci-device-refcount-leak-in-pch_reque.patch
+tty-serial-clean-up-stop-tx-part-in-altera_uart_tx_c.patch
+tty-serial-altera_uart_-r-t-x_chars-need-only-uart_p.patch
+serial-altera_uart-fix-locking-in-polling-mode.patch
+serial-sunsab-fix-error-handling-in-sunsab_init.patch
+test_firmware-fix-memory-leak-in-test_firmware_init.patch
+misc-ocxl-fix-possible-name-leak-in-ocxl_file_regist.patch
+ocxl-fix-pci-device-refcount-leak-when-calling-get_f.patch
+misc-tifm-fix-possible-memory-leak-in-tifm_7xx1_swit.patch
+misc-sgi-gru-fix-use-after-free-error-in-gru_set_con.patch
+firmware-raspberrypi-fix-possible-memory-leak-in-rpi.patch
+cxl-fix-possible-null-ptr-deref-in-cxl_guest_init_af.patch
+cxl-fix-possible-null-ptr-deref-in-cxl_pci_init_afu-.patch
+iio-temperature-ltc2983-make-bulk-write-buffer-dma-s.patch
+genirq-add-irqf_no_autoen-for-request_irq-nmi.patch
+iio-imu-adis-use-irqf_no_autoen-instead-of-irq-reque.patch
+iio-adis-handle-devices-that-cannot-unmask-the-drdy-.patch
+iio-adis-stylistic-changes.patch
+iio-imu-adis-move-exports-into-iio_adislib-namespace.patch
+iio-adis-add-__adis_enable_irq-implementation.patch
+counter-stm32-lptimer-cnt-fix-the-check-on-arr-and-c.patch
+usb-roles-fix-of-node-refcount-leak-in-usb_role_swit.patch
+usb-gadget-f_hid-optional-setup-set_report-mode.patch
+usb-gadget-f_hid-fix-f_hidg-lifetime-vs-cdev.patch
+usb-gadget-f_hid-fix-refcount-leak-on-error-path.patch
+drivers-mcb-fix-resource-leak-in-mcb_probe.patch
+mcb-mcb-parse-fix-error-handing-in-chameleon_parse_g.patch
+chardev-fix-error-handling-in-cdev_device_add.patch
+i2c-pxa-pci-fix-missing-pci_disable_device-on-error-.patch
+staging-rtl8192u-fix-use-after-free-in-ieee80211_rx.patch
+staging-rtl8192e-fix-potential-use-after-free-in-rtl.patch
+vme-fix-error-not-catched-in-fake_init.patch
+gpiolib-get-rid-of-redundant-else.patch
+gpiolib-cdev-fix-null-pointer-dereferences.patch
+i2c-mux-reg-check-return-value-after-calling-platfor.patch
+i2c-ismt-fix-an-out-of-bounds-bug-in-ismt_access.patch
+usb-storage-add-check-for-kcalloc.patch
+tracing-hist-fix-issue-of-losting-command-info-in-er.patch
+samples-vfio-mdev-fix-missing-pci_disable_device-in-.patch
+thermal-drivers-imx8mm_thermal-validate-temperature-.patch
+fbdev-ssd1307fb-drop-optional-dependency.patch
+fbdev-pm2fb-fix-missing-pci_disable_device.patch
+fbdev-via-fix-error-in-via_core_init.patch
+fbdev-vermilion-decrease-reference-count-in-error-pa.patch
+fbdev-uvesafb-fixes-an-error-handling-path-in-uvesaf.patch
+hsi-omap_ssi_core-fix-unbalanced-pm_runtime_disable.patch
+hsi-omap_ssi_core-fix-possible-memory-leak-in-ssi_pr.patch
+power-supply-fix-residue-sysfs-file-in-error-handle-.patch
+perf-trace-return-error-if-a-system-call-doesn-t-exi.patch
+perf-trace-use-macro-raw_syscall_args_num-to-replace.patch
+perf-trace-handle-failure-when-trace-point-folder-is.patch
+perf-symbol-correction-while-adjusting-symbol.patch
+hsi-omap_ssi_core-fix-error-handling-in-ssi_init.patch
+power-supply-fix-null-pointer-dereferencing-in-power.patch
+rdma-siw-fix-pointer-cast-warning.patch
+iommu-sun50i-fix-reset-release.patch
+iommu-sun50i-consider-all-fault-sources-for-reset.patch
+iommu-sun50i-fix-r-w-permission-check.patch
+iommu-sun50i-fix-flush-size.patch
+phy-usb-s2-wol-wakeup_count-not-incremented-for-usb-.patch
+include-uapi-linux-swab-fix-potentially-missing-__al.patch
+pwm-tegra-improve-required-rate-calculation.patch
+dmaengine-idxd-fix-crc_val-field-for-completion-reco.patch
+rtc-rtc-cmos-do-not-check-acpi_fadt_low_power_s0.patch
+rtc-cmos-fix-event-handler-registration-ordering-iss.patch
+rtc-cmos-fix-wake-alarm-breakage.patch
+rtc-cmos-fix-build-on-non-acpi-platforms.patch
+rtc-cmos-call-cmos_wake_setup-from-cmos_do_probe.patch
+rtc-cmos-call-rtc_wake_setup-from-cmos_do_probe.patch
+rtc-cmos-eliminate-forward-declarations-of-some-func.patch
+rtc-cmos-rename-acpi-related-functions.patch
+rtc-cmos-disable-acpi-rtc-event-on-removal.patch
+rtc-snvs-allow-a-time-difference-on-clock-register-r.patch
+rtc-pcf85063-fix-reading-alarm.patch
+iommu-amd-fix-pci-device-refcount-leak-in-ppr_notifi.patch
+iommu-fsl_pamu-fix-resource-leak-in-fsl_pamu_probe.patch
+macintosh-fix-possible-memory-leak-in-macio_add_one_.patch
+macintosh-macio-adb-check-the-return-value-of-iorema.patch
+powerpc-52xx-fix-a-resource-leak-in-an-error-handlin.patch
+cxl-fix-refcount-leak-in-cxl_calc_capp_routing.patch
+powerpc-xmon-enable-breakpoints-on-8xx.patch
+powerpc-xmon-fix-wswitch-unreachable-warning-in-bpt_.patch
+powerpc-xive-add-missing-iounmap-in-error-path-in-xi.patch
+kbuild-remove-unneeded-mkdir-for-external-modules_in.patch
+kbuild-unify-modules-_install-for-in-tree-and-extern.patch
+phy-qcom-qmp-create-copies-of-qmp-phy-driver.patch
+kbuild-refactor-single-builds-of-.ko.patch
+phy-qcom-qmp-combo-fix-runtime-suspend.patch
+powerpc-perf-callchain-validate-kernel-stack-pointer.patch
+powerpc-83xx-mpc832x_rdb-call-platform_device_put-in.patch
+powerpc-hv-gpci-fix-hv_gpci-event-list.patch
+selftests-powerpc-fix-resource-leaks.patch
+iommu-sun50i-remove-iommu_domain_identity.patch
+pwm-sifive-call-pwm_sifive_update_clock-while-mutex-.patch
+remoteproc-sysmon-fix-memory-leak-in-qcom_add_sysmon.patch
+remoteproc-qcom_q6v5_pas-disable-wakeup-on-probe-fai.patch
+remoteproc-qcom_q6v5_pas-detach-power-domains-on-rem.patch
+remoteproc-qcom_q6v5_pas-fix-missing-of_node_put-in-.patch
+powerpc-eeh-drop-redundant-spinlock-initialization.patch
+powerpc-pseries-eeh-use-correct-api-for-error-log-si.patch
+mfd-qcom_rpm-fix-an-error-handling-path-in-qcom_rpm_.patch
+netfilter-flowtable-really-fix-nat-ipv6-offload.patch
+rtc-st-lpc-add-missing-clk_disable_unprepare-in-st_r.patch
+rtc-pic32-move-devm_rtc_allocate_device-earlier-in-p.patch
+rtc-pcf85063-fix-pcf85063_clkout_control.patch
+nfsd-remove-spurious-cb_setup_err-tracepoint.patch
+nfsd-under-nfsv4.1-fix-double-svc_xprt_put-on-rpc_cr.patch
+net-macsec-fix-net-device-access-prior-to-holding-a-.patch
+misdn-hfcsusb-don-t-call-dev_kfree_skb-kfree_skb-und.patch
+misdn-hfcpci-don-t-call-dev_kfree_skb-kfree_skb-unde.patch
+misdn-hfcmulti-don-t-call-dev_kfree_skb-kfree_skb-un.patch
+nfc-pn533-clear-nfc_target-before-being-used.patch
+r6040-fix-kmemleak-in-probe-and-remove.patch
+net-switch-to-storing-kcov-handle-directly-in-sk_buf.patch
+net-add-inline-function-skb_csum_is_sctp.patch
+net-igc-use-skb_csum_is_sctp-instead-of-protocol-che.patch
+net-add-a-helper-to-avoid-issues-with-hw-tx-timestam.patch
+igc-enhance-qbv-scheduling-by-using-first-flag-bit.patch
+igc-use-strict-cycles-for-qbv-scheduling.patch
+igc-add-checking-for-basetime-less-than-zero.patch
+igc-recalculate-qbv-end_time-by-considering-cycle-ti.patch
+igc-lift-taprio-schedule-restriction.patch
+igc-set-qbv-start_time-and-end_time-to-end_time-if-n.patch
+rtc-mxc_v2-add-missing-clk_disable_unprepare.patch
+selftests-devlink-fix-the-fd-redirect-in-dummy_repor.patch
+openvswitch-fix-flow-lookup-to-use-unmasked-key.patch
+skbuff-account-for-tail-adjustment-during-pull-opera.patch
+mailbox-zynq-ipi-fix-error-handling-while-device_reg.patch
+net_sched-reject-tcf_em_simple-case-for-complex-emat.patch
+rxrpc-fix-missing-unlock-in-rxrpc_do_sendmsg.patch
+myri10ge-fix-an-error-handling-path-in-myri10ge_prob.patch
+net-stream-purge-sk_error_queue-in-sk_stream_kill_qu.patch
+rcu-fix-__this_cpu_read-lockdep-warning-in-rcu_force.patch
+arm64-make-is_ttbrx_addr-noinstr-safe.patch
+video-hyperv_fb-avoid-taking-busy-spinlock-on-panic-.patch
+x86-hyperv-remove-unregister-syscore-call-from-hyper.patch
+binfmt_misc-fix-shift-out-of-bounds-in-check_special.patch
+fs-jfs-fix-shift-out-of-bounds-in-dballocag.patch
+udf-avoid-double-brelse-in-udf_rename.patch
+fs-jfs-fix-shift-out-of-bounds-in-dbdiscardag.patch
+acpica-fix-error-code-path-in-acpi_ds_call_control_m.patch
+nilfs2-fix-shift-out-of-bounds-overflow-in-nilfs_sb2.patch
+nilfs2-fix-shift-out-of-bounds-due-to-too-large-expo.patch
+acct-fix-potential-integer-overflow-in-encode_comp_t.patch
+hfs-fix-oob-read-in-__hfs_brec_find.patch
+drm-etnaviv-add-missing-quirks-for-gc300.patch
+brcmfmac-return-error-when-getting-invalid-max_flowr.patch
+wifi-ath9k-verify-the-expected-usb_endpoints-are-pre.patch
+wifi-ar5523-fix-use-after-free-on-ar5523_cmd-timed-o.patch
+asoc-codecs-rt298-add-quirk-for-kbl-r-rvp-platform.patch
+ipmi-fix-memleak-when-unload-ipmi-driver.patch
+drm-amd-display-prevent-memory-leak.patch
+qed-gcc13-use-u16-for-fid-to-be-big-enough.patch
+bpf-make-sure-skb-len-0-when-redirecting-to-a-tunnel.patch
+net-ethernet-ti-fix-return-type-of-netcp_ndo_start_x.patch
+hamradio-baycom_epp-fix-return-type-of-baycom_send_p.patch
+wifi-brcmfmac-fix-potential-shift-out-of-bounds-in-b.patch
+igb-do-not-free-q_vector-unless-new-one-was-allocate.patch
+drm-amdgpu-fix-type-of-second-parameter-in-trans_msg.patch
+drm-amdgpu-fix-type-of-second-parameter-in-odn_edit_.patch
+s390-ctcm-fix-return-type-of-ctc-mp-m_tx.patch
+s390-netiucv-fix-return-type-of-netiucv_tx.patch
+s390-lcs-fix-return-type-of-lcs_start_xmit.patch
+drm-msm-use-drm_mode_copy.patch
+drm-rockchip-use-drm_mode_copy.patch
+drm-sti-use-drm_mode_copy.patch
+drivers-md-md-bitmap-check-the-return-value-of-md_bi.patch
+md-raid1-stop-mdx_raid1-thread-when-raid1-array-run-.patch
+drm-amd-display-fix-array-index-out-of-bound-error-i.patch
+net-add-atomic_long_t-to-net_device_stats-fields.patch
+mrp-introduce-active-flags-to-prevent-uaf-when-appli.patch
+ppp-associate-skb-with-a-device-at-tx.patch
+bpf-prevent-decl_tag-from-being-referenced-in-func_p.patch
+ethtool-avoiding-integer-overflow-in-ethtool_phys_id.patch
+media-dvb-frontends-fix-leak-of-memory-fw.patch
+media-dvbdev-adopts-refcnt-to-avoid-uaf.patch
+media-dvb-usb-fix-memory-leak-in-dvb_usb_adapter_ini.patch
+blk-mq-fix-possible-memleak-when-register-hctx-faile.patch
+libbpf-avoid-enum-forward-declarations-in-public-api.patch
+regulator-core-fix-use_count-leakage-when-handling-b.patch
+mmc-f-sdh30-add-quirks-for-broken-timeout-clock-capa.patch
+mmc-renesas_sdhi-better-reset-from-hs400-mode.patch
+media-si470x-fix-use-after-free-in-si470x_int_in_cal.patch
+clk-st-fix-memory-leak-in-st_of_quadfs_setup.patch
+hugetlbfs-fix-null-ptr-deref-in-hugetlbfs_parse_para.patch
+drm-fsl-dcu-fix-return-type-of-fsl_dcu_drm_connector.patch
+drm-sti-fix-return-type-of-sti_-dvo-hda-hdmi-_connec.patch
+orangefs-fix-kmemleak-in-orangefs_prepare_debugfs_he.patch
+orangefs-fix-kmemleak-in-orangefs_-kernel-client-_de.patch
diff --git a/queue-5.10/skbuff-account-for-tail-adjustment-during-pull-opera.patch b/queue-5.10/skbuff-account-for-tail-adjustment-during-pull-opera.patch
new file mode 100644 (file)
index 0000000..be21ebc
--- /dev/null
@@ -0,0 +1,66 @@
+From cd7225c2075b854c7cc27b8b7624a9bea3f45304 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Dec 2022 23:11:58 -0700
+Subject: skbuff: Account for tail adjustment during pull operations
+
+From: Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com>
+
+[ Upstream commit 2d7afdcbc9d32423f177ee12b7c93783aea338fb ]
+
+Extending the tail can have some unexpected side effects if a program uses
+a helper like BPF_FUNC_skb_pull_data to read partial content beyond the
+head skb headlen when all the skbs in the gso frag_list are linear with no
+head_frag -
+
+  kernel BUG at net/core/skbuff.c:4219!
+  pc : skb_segment+0xcf4/0xd2c
+  lr : skb_segment+0x63c/0xd2c
+  Call trace:
+   skb_segment+0xcf4/0xd2c
+   __udp_gso_segment+0xa4/0x544
+   udp4_ufo_fragment+0x184/0x1c0
+   inet_gso_segment+0x16c/0x3a4
+   skb_mac_gso_segment+0xd4/0x1b0
+   __skb_gso_segment+0xcc/0x12c
+   udp_rcv_segment+0x54/0x16c
+   udp_queue_rcv_skb+0x78/0x144
+   udp_unicast_rcv_skb+0x8c/0xa4
+   __udp4_lib_rcv+0x490/0x68c
+   udp_rcv+0x20/0x30
+   ip_protocol_deliver_rcu+0x1b0/0x33c
+   ip_local_deliver+0xd8/0x1f0
+   ip_rcv+0x98/0x1a4
+   deliver_ptype_list_skb+0x98/0x1ec
+   __netif_receive_skb_core+0x978/0xc60
+
+Fix this by marking these skbs as GSO_DODGY so segmentation can handle
+the tail updates accordingly.
+
+Fixes: 3dcbdb134f32 ("net: gso: Fix skb_segment splat when splitting gso_size mangled skb having linear-headed frag_list")
+Signed-off-by: Sean Tranchetti <quic_stranche@quicinc.com>
+Signed-off-by: Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com>
+Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
+Link: https://lore.kernel.org/r/1671084718-24796-1-git-send-email-quic_subashab@quicinc.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 176bcbb07aab..2b12e0730b85 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -2115,6 +2115,9 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta)
+                               insp = list;
+                       } else {
+                               /* Eaten partially. */
++                              if (skb_is_gso(skb) && !list->head_frag &&
++                                  skb_headlen(list))
++                                      skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+                               if (skb_shared(list)) {
+                                       /* Sucks! We need to fork list. :-( */
+-- 
+2.35.1
+
diff --git a/queue-5.10/soc-qcom-apr-add-check-for-idr_alloc-and-of_property.patch b/queue-5.10/soc-qcom-apr-add-check-for-idr_alloc-and-of_property.patch
new file mode 100644 (file)
index 0000000..43fa541
--- /dev/null
@@ -0,0 +1,64 @@
+From 43ff692b8a1f7564810cceb2d53d922b55f234b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Nov 2022 09:44:03 +0800
+Subject: soc: qcom: apr: Add check for idr_alloc and
+ of_property_read_string_index
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 6d7860f5750d73da2fa1a1f6c9405058a593fa32 ]
+
+As idr_alloc() and of_property_read_string_index() can return negative
+numbers, it should be better to check the return value and deal with
+the exception.
+Therefore, it should be better to use goto statement to stop and return
+error.
+
+Fixes: 6adba21eb434 ("soc: qcom: Add APR bus driver")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221107014403.3606-1-jiasheng@iscas.ac.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/apr.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
+index 8fed91822cae..7063e0d42c5e 100644
+--- a/drivers/soc/qcom/apr.c
++++ b/drivers/soc/qcom/apr.c
+@@ -312,11 +312,19 @@ static int apr_add_device(struct device *dev, struct device_node *np,
+       adev->dev.driver = NULL;
+       spin_lock(&apr->svcs_lock);
+-      idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
++      ret = idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
+       spin_unlock(&apr->svcs_lock);
++      if (ret < 0) {
++              dev_err(dev, "idr_alloc failed: %d\n", ret);
++              goto out;
++      }
+-      of_property_read_string_index(np, "qcom,protection-domain",
+-                                    1, &adev->service_path);
++      ret = of_property_read_string_index(np, "qcom,protection-domain",
++                                          1, &adev->service_path);
++      if (ret < 0) {
++              dev_err(dev, "Failed to read second value of qcom,protection-domain\n");
++              goto out;
++      }
+       dev_info(dev, "Adding APR dev: %s\n", dev_name(&adev->dev));
+@@ -326,6 +334,7 @@ static int apr_add_device(struct device *dev, struct device_node *np,
+               put_device(&adev->dev);
+       }
++out:
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/soc-qcom-apr-make-code-more-reuseable.patch b/queue-5.10/soc-qcom-apr-make-code-more-reuseable.patch
new file mode 100644 (file)
index 0000000..73098bf
--- /dev/null
@@ -0,0 +1,413 @@
+From 161e3f0ec234f9a748a8b96f8831e9d3e4a10836 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Sep 2021 14:55:40 +0100
+Subject: soc: qcom: apr: make code more reuseable
+
+From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+
+[ Upstream commit 99139b80c1b3d73026ed8be2de42c52e2976ab64 ]
+
+APR and other packet routers like GPR are pretty much same and
+interact with other drivers in similar way.
+
+Ex: GPR ports can be considered as APR services, only difference
+is they are allocated dynamically.
+
+Other difference is packet layout, which should not matter
+with the apis abstracted. Apart from this the rest of the
+functionality is pretty much identical across APR and GPR.
+
+Make the apr code more reusable by abstracting it service level,
+rather than device level so that we do not need to write
+new drivers for other new packet routers like GPR.
+
+This patch is in preparation to add GPR support to this driver.
+
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20210927135559.738-4-srinivas.kandagatla@linaro.org
+Stable-dep-of: 6d7860f5750d ("soc: qcom: apr: Add check for idr_alloc and of_property_read_string_index")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/apr.c       | 129 +++++++++++++++++++++--------------
+ include/linux/soc/qcom/apr.h |  12 +++-
+ 2 files changed, 90 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
+index f736d208362c..8fed91822cae 100644
+--- a/drivers/soc/qcom/apr.c
++++ b/drivers/soc/qcom/apr.c
+@@ -15,13 +15,18 @@
+ #include <linux/rpmsg.h>
+ #include <linux/of.h>
+-struct apr {
++enum {
++      PR_TYPE_APR = 0,
++};
++
++struct packet_router {
+       struct rpmsg_endpoint *ch;
+       struct device *dev;
+       spinlock_t svcs_lock;
+       spinlock_t rx_lock;
+       struct idr svcs_idr;
+       int dest_domain_id;
++      int type;
+       struct pdr_handle *pdr;
+       struct workqueue_struct *rxwq;
+       struct work_struct rx_work;
+@@ -44,21 +49,21 @@ struct apr_rx_buf {
+  */
+ int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt)
+ {
+-      struct apr *apr = dev_get_drvdata(adev->dev.parent);
++      struct packet_router *apr = dev_get_drvdata(adev->dev.parent);
+       struct apr_hdr *hdr;
+       unsigned long flags;
+       int ret;
+-      spin_lock_irqsave(&adev->lock, flags);
++      spin_lock_irqsave(&adev->svc.lock, flags);
+       hdr = &pkt->hdr;
+       hdr->src_domain = APR_DOMAIN_APPS;
+-      hdr->src_svc = adev->svc_id;
++      hdr->src_svc = adev->svc.id;
+       hdr->dest_domain = adev->domain_id;
+-      hdr->dest_svc = adev->svc_id;
++      hdr->dest_svc = adev->svc.id;
+       ret = rpmsg_trysend(apr->ch, pkt, hdr->pkt_size);
+-      spin_unlock_irqrestore(&adev->lock, flags);
++      spin_unlock_irqrestore(&adev->svc.lock, flags);
+       return ret ? ret : hdr->pkt_size;
+ }
+@@ -74,7 +79,7 @@ static void apr_dev_release(struct device *dev)
+ static int apr_callback(struct rpmsg_device *rpdev, void *buf,
+                                 int len, void *priv, u32 addr)
+ {
+-      struct apr *apr = dev_get_drvdata(&rpdev->dev);
++      struct packet_router *apr = dev_get_drvdata(&rpdev->dev);
+       struct apr_rx_buf *abuf;
+       unsigned long flags;
+@@ -100,11 +105,11 @@ static int apr_callback(struct rpmsg_device *rpdev, void *buf,
+       return 0;
+ }
+-
+-static int apr_do_rx_callback(struct apr *apr, struct apr_rx_buf *abuf)
++static int apr_do_rx_callback(struct packet_router *apr, struct apr_rx_buf *abuf)
+ {
+       uint16_t hdr_size, msg_type, ver, svc_id;
+-      struct apr_device *svc = NULL;
++      struct pkt_router_svc *svc;
++      struct apr_device *adev;
+       struct apr_driver *adrv = NULL;
+       struct apr_resp_pkt resp;
+       struct apr_hdr *hdr;
+@@ -145,12 +150,15 @@ static int apr_do_rx_callback(struct apr *apr, struct apr_rx_buf *abuf)
+       svc_id = hdr->dest_svc;
+       spin_lock_irqsave(&apr->svcs_lock, flags);
+       svc = idr_find(&apr->svcs_idr, svc_id);
+-      if (svc && svc->dev.driver)
+-              adrv = to_apr_driver(svc->dev.driver);
++      if (svc && svc->dev->driver) {
++              adev = svc_to_apr_device(svc);
++              adrv = to_apr_driver(adev->dev.driver);
++      }
+       spin_unlock_irqrestore(&apr->svcs_lock, flags);
+-      if (!adrv) {
+-              dev_err(apr->dev, "APR: service is not registered\n");
++      if (!adrv || !adev) {
++              dev_err(apr->dev, "APR: service is not registered (%d)\n",
++                      svc_id);
+               return -EINVAL;
+       }
+@@ -164,20 +172,26 @@ static int apr_do_rx_callback(struct apr *apr, struct apr_rx_buf *abuf)
+       if (resp.payload_size > 0)
+               resp.payload = buf + hdr_size;
+-      adrv->callback(svc, &resp);
++      adrv->callback(adev, &resp);
+       return 0;
+ }
+ static void apr_rxwq(struct work_struct *work)
+ {
+-      struct apr *apr = container_of(work, struct apr, rx_work);
++      struct packet_router *apr = container_of(work, struct packet_router, rx_work);
+       struct apr_rx_buf *abuf, *b;
+       unsigned long flags;
+       if (!list_empty(&apr->rx_list)) {
+               list_for_each_entry_safe(abuf, b, &apr->rx_list, node) {
+-                      apr_do_rx_callback(apr, abuf);
++                      switch (apr->type) {
++                      case PR_TYPE_APR:
++                              apr_do_rx_callback(apr, abuf);
++                              break;
++                      default:
++                              break;
++                      }
+                       spin_lock_irqsave(&apr->rx_lock, flags);
+                       list_del(&abuf->node);
+                       spin_unlock_irqrestore(&apr->rx_lock, flags);
+@@ -201,7 +215,7 @@ static int apr_device_match(struct device *dev, struct device_driver *drv)
+       while (id->domain_id != 0 || id->svc_id != 0) {
+               if (id->domain_id == adev->domain_id &&
+-                  id->svc_id == adev->svc_id)
++                  id->svc_id == adev->svc.id)
+                       return 1;
+               id++;
+       }
+@@ -221,14 +235,14 @@ static int apr_device_remove(struct device *dev)
+ {
+       struct apr_device *adev = to_apr_device(dev);
+       struct apr_driver *adrv;
+-      struct apr *apr = dev_get_drvdata(adev->dev.parent);
++      struct packet_router *apr = dev_get_drvdata(adev->dev.parent);
+       if (dev->driver) {
+               adrv = to_apr_driver(dev->driver);
+               if (adrv->remove)
+                       adrv->remove(adev);
+               spin_lock(&apr->svcs_lock);
+-              idr_remove(&apr->svcs_idr, adev->svc_id);
++              idr_remove(&apr->svcs_idr, adev->svc.id);
+               spin_unlock(&apr->svcs_lock);
+       }
+@@ -257,28 +271,39 @@ struct bus_type aprbus = {
+ EXPORT_SYMBOL_GPL(aprbus);
+ static int apr_add_device(struct device *dev, struct device_node *np,
+-                        const struct apr_device_id *id)
++                        u32 svc_id, u32 domain_id)
+ {
+-      struct apr *apr = dev_get_drvdata(dev);
++      struct packet_router *apr = dev_get_drvdata(dev);
+       struct apr_device *adev = NULL;
++      struct pkt_router_svc *svc;
+       int ret;
+       adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+       if (!adev)
+               return -ENOMEM;
+-      spin_lock_init(&adev->lock);
++      adev->svc_id = svc_id;
++      svc = &adev->svc;
++
++      svc->id = svc_id;
++      svc->pr = apr;
++      svc->priv = adev;
++      svc->dev = dev;
++      spin_lock_init(&svc->lock);
++
++      adev->domain_id = domain_id;
+-      adev->svc_id = id->svc_id;
+-      adev->domain_id = id->domain_id;
+-      adev->version = id->svc_version;
+       if (np)
+               snprintf(adev->name, APR_NAME_SIZE, "%pOFn", np);
+-      else
+-              strscpy(adev->name, id->name, APR_NAME_SIZE);
+-      dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
+-                   id->domain_id, id->svc_id);
++      switch (apr->type) {
++      case PR_TYPE_APR:
++              dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
++                           domain_id, svc_id);
++              break;
++      default:
++              break;
++      }
+       adev->dev.bus = &aprbus;
+       adev->dev.parent = dev;
+@@ -287,8 +312,7 @@ static int apr_add_device(struct device *dev, struct device_node *np,
+       adev->dev.driver = NULL;
+       spin_lock(&apr->svcs_lock);
+-      idr_alloc(&apr->svcs_idr, adev, id->svc_id,
+-                id->svc_id + 1, GFP_ATOMIC);
++      idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
+       spin_unlock(&apr->svcs_lock);
+       of_property_read_string_index(np, "qcom,protection-domain",
+@@ -308,7 +332,7 @@ static int apr_add_device(struct device *dev, struct device_node *np,
+ static int of_apr_add_pd_lookups(struct device *dev)
+ {
+       const char *service_name, *service_path;
+-      struct apr *apr = dev_get_drvdata(dev);
++      struct packet_router *apr = dev_get_drvdata(dev);
+       struct device_node *node;
+       struct pdr_service *pds;
+       int ret;
+@@ -340,13 +364,14 @@ static int of_apr_add_pd_lookups(struct device *dev)
+ static void of_register_apr_devices(struct device *dev, const char *svc_path)
+ {
+-      struct apr *apr = dev_get_drvdata(dev);
++      struct packet_router *apr = dev_get_drvdata(dev);
+       struct device_node *node;
+       const char *service_path;
+       int ret;
+       for_each_child_of_node(dev->of_node, node) {
+-              struct apr_device_id id = { {0} };
++              u32 svc_id;
++              u32 domain_id;
+               /*
+                * This function is called with svc_path NULL during
+@@ -376,13 +401,13 @@ static void of_register_apr_devices(struct device *dev, const char *svc_path)
+                               continue;
+               }
+-              if (of_property_read_u32(node, "reg", &id.svc_id))
++              if (of_property_read_u32(node, "reg", &svc_id))
+                       continue;
+-              id.domain_id = apr->dest_domain_id;
++              domain_id = apr->dest_domain_id;
+-              if (apr_add_device(dev, node, &id))
+-                      dev_err(dev, "Failed to add apr %d svc\n", id.svc_id);
++              if (apr_add_device(dev, node, svc_id, domain_id))
++                      dev_err(dev, "Failed to add apr %d svc\n", svc_id);
+       }
+ }
+@@ -402,7 +427,7 @@ static int apr_remove_device(struct device *dev, void *svc_path)
+ static void apr_pd_status(int state, char *svc_path, void *priv)
+ {
+-      struct apr *apr = (struct apr *)priv;
++      struct packet_router *apr = (struct packet_router *)priv;
+       switch (state) {
+       case SERVREG_SERVICE_STATE_UP:
+@@ -417,16 +442,20 @@ static void apr_pd_status(int state, char *svc_path, void *priv)
+ static int apr_probe(struct rpmsg_device *rpdev)
+ {
+       struct device *dev = &rpdev->dev;
+-      struct apr *apr;
++      struct packet_router *apr;
+       int ret;
+       apr = devm_kzalloc(dev, sizeof(*apr), GFP_KERNEL);
+       if (!apr)
+               return -ENOMEM;
+-      ret = of_property_read_u32(dev->of_node, "qcom,apr-domain", &apr->dest_domain_id);
++      ret = of_property_read_u32(dev->of_node, "qcom,domain", &apr->dest_domain_id);
++      if (ret) /* try deprecated apr-domain property */
++              ret = of_property_read_u32(dev->of_node, "qcom,apr-domain",
++                                         &apr->dest_domain_id);
++      apr->type = PR_TYPE_APR;
+       if (ret) {
+-              dev_err(dev, "APR Domain ID not specified in DT\n");
++              dev_err(dev, "Domain ID not specified in DT\n");
+               return ret;
+       }
+@@ -469,7 +498,7 @@ static int apr_probe(struct rpmsg_device *rpdev)
+ static void apr_remove(struct rpmsg_device *rpdev)
+ {
+-      struct apr *apr = dev_get_drvdata(&rpdev->dev);
++      struct packet_router *apr = dev_get_drvdata(&rpdev->dev);
+       pdr_handle_release(apr->pdr);
+       device_for_each_child(&rpdev->dev, NULL, apr_remove_device);
+@@ -506,20 +535,20 @@ void apr_driver_unregister(struct apr_driver *drv)
+ }
+ EXPORT_SYMBOL_GPL(apr_driver_unregister);
+-static const struct of_device_id apr_of_match[] = {
++static const struct of_device_id pkt_router_of_match[] = {
+       { .compatible = "qcom,apr"},
+       { .compatible = "qcom,apr-v2"},
+       {}
+ };
+-MODULE_DEVICE_TABLE(of, apr_of_match);
++MODULE_DEVICE_TABLE(of, pkt_router_of_match);
+-static struct rpmsg_driver apr_driver = {
++static struct rpmsg_driver packet_router_driver = {
+       .probe = apr_probe,
+       .remove = apr_remove,
+       .callback = apr_callback,
+       .drv = {
+               .name = "qcom,apr",
+-              .of_match_table = apr_of_match,
++              .of_match_table = pkt_router_of_match,
+       },
+ };
+@@ -529,7 +558,7 @@ static int __init apr_init(void)
+       ret = bus_register(&aprbus);
+       if (!ret)
+-              ret = register_rpmsg_driver(&apr_driver);
++              ret = register_rpmsg_driver(&packet_router_driver);
+       else
+               bus_unregister(&aprbus);
+@@ -539,7 +568,7 @@ static int __init apr_init(void)
+ static void __exit apr_exit(void)
+ {
+       bus_unregister(&aprbus);
+-      unregister_rpmsg_driver(&apr_driver);
++      unregister_rpmsg_driver(&packet_router_driver);
+ }
+ subsys_initcall(apr_init);
+diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h
+index 7f0bc3cf4d61..6374763186c8 100644
+--- a/include/linux/soc/qcom/apr.h
++++ b/include/linux/soc/qcom/apr.h
+@@ -79,6 +79,15 @@ struct apr_resp_pkt {
+ #define APR_SVC_MAJOR_VERSION(v)      ((v >> 16) & 0xFF)
+ #define APR_SVC_MINOR_VERSION(v)      (v & 0xFF)
++struct packet_router;
++struct pkt_router_svc {
++      struct device *dev;
++      struct packet_router *pr;
++      spinlock_t lock;
++      int id;
++      void *priv;
++};
++
+ struct apr_device {
+       struct device   dev;
+       uint16_t        svc_id;
+@@ -86,11 +95,12 @@ struct apr_device {
+       uint32_t        version;
+       char name[APR_NAME_SIZE];
+       const char *service_path;
+-      spinlock_t      lock;
++      struct pkt_router_svc svc;
+       struct list_head node;
+ };
+ #define to_apr_device(d) container_of(d, struct apr_device, dev)
++#define svc_to_apr_device(d) container_of(d, struct apr_device, svc)
+ struct apr_driver {
+       int     (*probe)(struct apr_device *sl);
+-- 
+2.35.1
+
diff --git a/queue-5.10/soc-qcom-llcc-make-irq-truly-optional.patch b/queue-5.10/soc-qcom-llcc-make-irq-truly-optional.patch
new file mode 100644 (file)
index 0000000..a37acb0
--- /dev/null
@@ -0,0 +1,40 @@
+From 965b6e8a950d1569d9a8c626e3769ffb6e786b47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 16:30:41 +0100
+Subject: soc: qcom: llcc: make irq truly optional
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit c882c899ead3545102a4d71b5fbe73b9e4bc2657 ]
+
+The function platform_get_irq prints an error message into the kernel
+log when the irq isn't found.
+
+Since the interrupt is actually optional and not provided by some SoCs,
+use platform_get_irq_optional which does not print an error message.
+
+Fixes: c081f3060fab ("soc: qcom: Add support to register LLCC EDAC driver")
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221104153041.412020-1-luca.weiss@fairphone.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/llcc-qcom.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
+index 2e06f48d683d..c60fe98f03e3 100644
+--- a/drivers/soc/qcom/llcc-qcom.c
++++ b/drivers/soc/qcom/llcc-qcom.c
+@@ -476,7 +476,7 @@ static int qcom_llcc_probe(struct platform_device *pdev)
+       if (ret)
+               goto err;
+-      drv_data->ecc_irq = platform_get_irq(pdev, 0);
++      drv_data->ecc_irq = platform_get_irq_optional(pdev, 0);
+       if (drv_data->ecc_irq >= 0) {
+               llcc_edac = platform_device_register_data(&pdev->dev,
+                                               "qcom_llcc_edac", -1, drv_data,
+-- 
+2.35.1
+
diff --git a/queue-5.10/soc-ti-knav_qmss_queue-fix-pm-disable-depth-imbalanc.patch b/queue-5.10/soc-ti-knav_qmss_queue-fix-pm-disable-depth-imbalanc.patch
new file mode 100644 (file)
index 0000000..69a1a88
--- /dev/null
@@ -0,0 +1,38 @@
+From 84c6862f93b434eb7e7c40950bc795d511732819 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 16:03:21 +0800
+Subject: soc: ti: knav_qmss_queue: Fix PM disable depth imbalance in
+ knav_queue_probe
+
+From: Zhang Qilong <zhangqilong3@huawei.com>
+
+[ Upstream commit e961c0f19450fd4a26bd043dd2979990bf12caf6 ]
+
+The pm_runtime_enable will increase power disable depth. Thus
+a pairing decrement is needed on the error handling path to
+keep it balanced according to context.
+
+Fixes: 41f93af900a2 ("soc: ti: add Keystone Navigator QMSS driver")
+Signed-off-by: Zhang Qilong <zhangqilong3@huawei.com>
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Link: https://lore.kernel.org/r/20221108080322.52268-2-zhangqilong3@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/ti/knav_qmss_queue.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
+index 38e2630eec36..20c84741639e 100644
+--- a/drivers/soc/ti/knav_qmss_queue.c
++++ b/drivers/soc/ti/knav_qmss_queue.c
+@@ -1784,6 +1784,7 @@ static int knav_queue_probe(struct platform_device *pdev)
+       pm_runtime_enable(&pdev->dev);
+       ret = pm_runtime_resume_and_get(&pdev->dev);
+       if (ret < 0) {
++              pm_runtime_disable(&pdev->dev);
+               dev_err(dev, "Failed to enable QMSS\n");
+               return ret;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/soc-ti-knav_qmss_queue-use-pm_runtime_resume_and_get.patch b/queue-5.10/soc-ti-knav_qmss_queue-use-pm_runtime_resume_and_get.patch
new file mode 100644 (file)
index 0000000..b5de9d3
--- /dev/null
@@ -0,0 +1,41 @@
+From 652d55f912ae105f4497d5b651a9ae3a662ceca5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Apr 2022 06:29:55 +0000
+Subject: soc: ti: knav_qmss_queue: Use pm_runtime_resume_and_get instead of
+ pm_runtime_get_sync
+
+From: Minghao Chi <chi.minghao@zte.com.cn>
+
+[ Upstream commit 12eeb74925da70eb39d90abead9de9793be3d4c8 ]
+
+Using pm_runtime_resume_and_get is more appropriate for simplifying
+code.
+
+Reported-by: Zeal Robot <zealci@zte.com.cn>
+Signed-off-by: Minghao Chi <chi.minghao@zte.com.cn>
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Link: https://lore.kernel.org/r/20220418062955.2557949-1-chi.minghao@zte.com.cn
+Stable-dep-of: e961c0f19450 ("soc: ti: knav_qmss_queue: Fix PM disable depth imbalance in knav_queue_probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/ti/knav_qmss_queue.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
+index baab7d558a69..38e2630eec36 100644
+--- a/drivers/soc/ti/knav_qmss_queue.c
++++ b/drivers/soc/ti/knav_qmss_queue.c
+@@ -1782,9 +1782,8 @@ static int knav_queue_probe(struct platform_device *pdev)
+       INIT_LIST_HEAD(&kdev->pdsps);
+       pm_runtime_enable(&pdev->dev);
+-      ret = pm_runtime_get_sync(&pdev->dev);
++      ret = pm_runtime_resume_and_get(&pdev->dev);
+       if (ret < 0) {
+-              pm_runtime_put_noidle(&pdev->dev);
+               dev_err(dev, "Failed to enable QMSS\n");
+               return ret;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/soc-ti-smartreflex-fix-pm-disable-depth-imbalance-in.patch b/queue-5.10/soc-ti-smartreflex-fix-pm-disable-depth-imbalance-in.patch
new file mode 100644 (file)
index 0000000..8b5dcf0
--- /dev/null
@@ -0,0 +1,37 @@
+From c84b132d9cf215fbff4f3a6c53ecb3762d2ebc0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 16:03:22 +0800
+Subject: soc: ti: smartreflex: Fix PM disable depth imbalance in omap_sr_probe
+
+From: Zhang Qilong <zhangqilong3@huawei.com>
+
+[ Upstream commit 69460e68eb662064ab4188d4e129ff31c1f23ed9 ]
+
+The pm_runtime_enable will increase power disable depth. Thus
+a pairing decrement is needed on the error handling path to
+keep it balanced according to context.
+
+Fixes: 984aa6dbf4ca ("OMAP3: PM: Adding smartreflex driver support.")
+Signed-off-by: Zhang Qilong <zhangqilong3@huawei.com>
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Link: https://lore.kernel.org/r/20221108080322.52268-3-zhangqilong3@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/ti/smartreflex.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c
+index 5376f3d22f31..1228a0cba132 100644
+--- a/drivers/soc/ti/smartreflex.c
++++ b/drivers/soc/ti/smartreflex.c
+@@ -942,6 +942,7 @@ static int omap_sr_probe(struct platform_device *pdev)
+ err_debugfs:
+       debugfs_remove_recursive(sr_info->dbg_dir);
+ err_list_del:
++      pm_runtime_disable(&pdev->dev);
+       list_del(&sr_info->node);
+       pm_runtime_put_sync(&pdev->dev);
+-- 
+2.35.1
+
diff --git a/queue-5.10/spi-spi-gpio-don-t-set-mosi-as-an-input-if-not-3wire.patch b/queue-5.10/spi-spi-gpio-don-t-set-mosi-as-an-input-if-not-3wire.patch
new file mode 100644 (file)
index 0000000..abeaae3
--- /dev/null
@@ -0,0 +1,64 @@
+From e279ca116dc4cd77c85f4e6ef8faefa0d0617b40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 15:08:53 -0800
+Subject: spi: spi-gpio: Don't set MOSI as an input if not 3WIRE mode
+
+From: Kris Bahnsen <kris@embeddedTS.com>
+
+[ Upstream commit 3a6f994f848a69deb2bf3cd9d130dd0c09730e55 ]
+
+The addition of 3WIRE support would affect MOSI direction even
+when still in standard (4 wire) mode. This can lead to MOSI being
+at an invalid logic level when a device driver sets an SPI
+message with a NULL tx_buf.
+
+spi.h states that if tx_buf is NULL then "zeros will be shifted
+out ... " If MOSI is tristated then the data shifted out is subject
+to pull resistors, keepers, or in the absence of those, noise.
+
+This issue came to light when using spi-gpio connected to an
+ADS7843 touchscreen controller. MOSI pulled high when clocking
+MISO data in caused the SPI device to interpret this as a command
+which would put the device in an unexpected and non-functional
+state.
+
+Fixes: 4b859db2c606 ("spi: spi-gpio: add SPI_3WIRE support")
+Fixes: 5132b3d28371 ("spi: gpio: Support 3WIRE high-impedance turn-around")
+Signed-off-by: Kris Bahnsen <kris@embeddedTS.com>
+Link: https://lore.kernel.org/r/20221207230853.6174-1-kris@embeddedTS.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-gpio.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
+index 0584f4d2fde2..3ffdab6caac2 100644
+--- a/drivers/spi/spi-gpio.c
++++ b/drivers/spi/spi-gpio.c
+@@ -244,9 +244,19 @@ static int spi_gpio_set_direction(struct spi_device *spi, bool output)
+       if (output)
+               return gpiod_direction_output(spi_gpio->mosi, 1);
+-      ret = gpiod_direction_input(spi_gpio->mosi);
+-      if (ret)
+-              return ret;
++      /*
++       * Only change MOSI to an input if using 3WIRE mode.
++       * Otherwise, MOSI could be left floating if there is
++       * no pull resistor connected to the I/O pin, or could
++       * be left logic high if there is a pull-up. Transmitting
++       * logic high when only clocking MISO data in can put some
++       * SPI devices in to a bad state.
++       */
++      if (spi->mode & SPI_3WIRE) {
++              ret = gpiod_direction_input(spi_gpio->mosi);
++              if (ret)
++                      return ret;
++      }
+       /*
+        * Send a turnaround high impedance cycle when switching
+        * from output to input. Theoretically there should be
+-- 
+2.35.1
+
diff --git a/queue-5.10/spi-spidev-mask-spi_cs_high-in-spi_ioc_rd_mode.patch b/queue-5.10/spi-spidev-mask-spi_cs_high-in-spi_ioc_rd_mode.patch
new file mode 100644 (file)
index 0000000..a136934
--- /dev/null
@@ -0,0 +1,83 @@
+From 9fc51aa2fc3b39cdd64d1aef21c9f5fa1bdfc91b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Nov 2022 17:29:27 +0100
+Subject: spi: spidev: mask SPI_CS_HIGH in SPI_IOC_RD_MODE
+
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+
+[ Upstream commit 7dbfa445ff7393d1c4c066c1727c9e0af1251958 ]
+
+Commit f3186dd87669 ("spi: Optionally use GPIO descriptors for CS GPIOs")
+has changed the user-space interface so that bogus SPI_CS_HIGH started
+to appear in the mask returned by SPI_IOC_RD_MODE even for active-low CS
+pins. Commit 138c9c32f090
+("spi: spidev: Fix CS polarity if GPIO descriptors are used") fixed only
+SPI_IOC_WR_MODE part of the problem. Let's fix SPI_IOC_RD_MODE
+symmetrically.
+
+Test case:
+
+       #include <sys/ioctl.h>
+       #include <fcntl.h>
+       #include <linux/spi/spidev.h>
+
+       int main(int argc, char **argv)
+       {
+               char modew = SPI_CPHA;
+               char moder;
+               int f = open("/dev/spidev0.0", O_RDWR);
+
+               if (f < 0)
+                       return 1;
+
+               ioctl(f, SPI_IOC_WR_MODE, &modew);
+               ioctl(f, SPI_IOC_RD_MODE, &moder);
+
+               return moder == modew ? 0 : 2;
+       }
+
+Fixes: f3186dd87669 ("spi: Optionally use GPIO descriptors for CS GPIOs")
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Link: https://lore.kernel.org/r/20221130162927.539512-1-alexander.sverdlin@siemens.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spidev.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
+index 859910ec8d9f..9c5ec99431d2 100644
+--- a/drivers/spi/spidev.c
++++ b/drivers/spi/spidev.c
+@@ -376,12 +376,23 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+       switch (cmd) {
+       /* read requests */
+       case SPI_IOC_RD_MODE:
+-              retval = put_user(spi->mode & SPI_MODE_MASK,
+-                                      (__u8 __user *)arg);
+-              break;
+       case SPI_IOC_RD_MODE32:
+-              retval = put_user(spi->mode & SPI_MODE_MASK,
+-                                      (__u32 __user *)arg);
++              tmp = spi->mode;
++
++              {
++                      struct spi_controller *ctlr = spi->controller;
++
++                      if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods &&
++                          ctlr->cs_gpiods[spi->chip_select])
++                              tmp &= ~SPI_CS_HIGH;
++              }
++
++              if (cmd == SPI_IOC_RD_MODE)
++                      retval = put_user(tmp & SPI_MODE_MASK,
++                                        (__u8 __user *)arg);
++              else
++                      retval = put_user(tmp & SPI_MODE_MASK,
++                                        (__u32 __user *)arg);
+               break;
+       case SPI_IOC_RD_LSB_FIRST:
+               retval = put_user((spi->mode & SPI_LSB_FIRST) ?  1 : 0,
+-- 
+2.35.1
+
diff --git a/queue-5.10/spi-update-reference-to-struct-spi_controller.patch b/queue-5.10/spi-update-reference-to-struct-spi_controller.patch
new file mode 100644 (file)
index 0000000..bfcbddf
--- /dev/null
@@ -0,0 +1,42 @@
+From 3c3fdd38b0db57b5d5897270cca81d67c46a6413 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 18:32:51 +0100
+Subject: spi: Update reference to struct spi_controller
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
+
+[ Upstream commit bf585ccee22faf469d82727cf375868105b362f7 ]
+
+struct spi_master has been renamed to struct spi_controller. Update the
+reference in spi.rst to make it clickable again.
+
+Fixes: 8caab75fd2c2 ("spi: Generalize SPI "master" to "controller"")
+Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
+Link: https://lore.kernel.org/r/20221101173252.1069294-1-j.neuschaefer@gmx.net
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/driver-api/spi.rst | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/driver-api/spi.rst b/Documentation/driver-api/spi.rst
+index f64cb666498a..f28887045049 100644
+--- a/Documentation/driver-api/spi.rst
++++ b/Documentation/driver-api/spi.rst
+@@ -25,8 +25,8 @@ hardware, which may be as simple as a set of GPIO pins or as complex as
+ a pair of FIFOs connected to dual DMA engines on the other side of the
+ SPI shift register (maximizing throughput). Such drivers bridge between
+ whatever bus they sit on (often the platform bus) and SPI, and expose
+-the SPI side of their device as a :c:type:`struct spi_master
+-<spi_master>`. SPI devices are children of that master,
++the SPI side of their device as a :c:type:`struct spi_controller
++<spi_controller>`. SPI devices are children of that master,
+ represented as a :c:type:`struct spi_device <spi_device>` and
+ manufactured from :c:type:`struct spi_board_info
+ <spi_board_info>` descriptors which are usually provided by
+-- 
+2.35.1
+
diff --git a/queue-5.10/staging-rtl8192e-fix-potential-use-after-free-in-rtl.patch b/queue-5.10/staging-rtl8192e-fix-potential-use-after-free-in-rtl.patch
new file mode 100644 (file)
index 0000000..303fbbd
--- /dev/null
@@ -0,0 +1,41 @@
+From 744c4eaa43094f375b325790641d94bc6057ff1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 16:12:53 +0800
+Subject: staging: rtl8192e: Fix potential use-after-free in
+ rtllib_rx_Monitor()
+
+From: YueHaibing <yuehaibing@huawei.com>
+
+[ Upstream commit d30f4436f364b4ad915ca2c09be07cd0f93ceb44 ]
+
+The skb is delivered to netif_rx() in rtllib_monitor_rx(), which may free it,
+after calling this, dereferencing skb may trigger use-after-free.
+Found by Smatch.
+
+Fixes: 94a799425eee ("From: wlanfae <wlanfae@realtek.com> [PATCH 1/8] rtl8192e: Import new version of driver from realtek")
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Link: https://lore.kernel.org/r/20221123081253.22296-1-yuehaibing@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/rtl8192e/rtllib_rx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c
+index 63752233e551..404794503fb6 100644
+--- a/drivers/staging/rtl8192e/rtllib_rx.c
++++ b/drivers/staging/rtl8192e/rtllib_rx.c
+@@ -1490,9 +1490,9 @@ static int rtllib_rx_Monitor(struct rtllib_device *ieee, struct sk_buff *skb,
+               hdrlen += 4;
+       }
+-      rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen);
+       ieee->stats.rx_packets++;
+       ieee->stats.rx_bytes += skb->len;
++      rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen);
+       return 1;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/staging-rtl8192u-fix-use-after-free-in-ieee80211_rx.patch b/queue-5.10/staging-rtl8192u-fix-use-after-free-in-ieee80211_rx.patch
new file mode 100644 (file)
index 0000000..b0103e9
--- /dev/null
@@ -0,0 +1,41 @@
+From b5908aabfc4196eec487b2a5c92f3ac1f161ffe2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 09:43:14 +0300
+Subject: staging: rtl8192u: Fix use after free in ieee80211_rx()
+
+From: Dan Carpenter <error27@gmail.com>
+
+[ Upstream commit bcc5e2dcf09089b337b76fc1a589f6ff95ca19ac ]
+
+We cannot dereference the "skb" pointer after calling
+ieee80211_monitor_rx(), because it is a use after free.
+
+Fixes: 8fc8598e61f6 ("Staging: Added Realtek rtl8192u driver to staging")
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Link: https://lore.kernel.org/r/Y33BArx3k/aw6yv/@kili
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+index b6fee7230ce0..3871437f4708 100644
+--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
++++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+@@ -954,9 +954,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+ #endif
+       if (ieee->iw_mode == IW_MODE_MONITOR) {
++              unsigned int len = skb->len;
++
+               ieee80211_monitor_rx(ieee, skb, rx_stats);
+               stats->rx_packets++;
+-              stats->rx_bytes += skb->len;
++              stats->rx_bytes += len;
+               return 1;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/staging-vme_user-fix-possible-uaf-in-tsi148_dma_list.patch b/queue-5.10/staging-vme_user-fix-possible-uaf-in-tsi148_dma_list.patch
new file mode 100644 (file)
index 0000000..06806ff
--- /dev/null
@@ -0,0 +1,44 @@
+From 325be428325accb11dae92e26daf1ae4eb6bffe6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 11:59:14 +0800
+Subject: staging: vme_user: Fix possible UAF in tsi148_dma_list_add
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 357057ee55d3c99a5de5abe8150f7bca04f8e53b ]
+
+Smatch report warning as follows:
+
+drivers/staging/vme_user/vme_tsi148.c:1757 tsi148_dma_list_add() warn:
+  '&entry->list' not removed from list
+
+In tsi148_dma_list_add(), the error path "goto err_dma" will not
+remove entry->list from list->entries, but entry will be freed,
+then list traversal may cause UAF.
+
+Fix by removeing it from list->entries before free().
+
+Fixes: b2383c90a9d6 ("vme: tsi148: fix first DMA item mapping")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Link: https://lore.kernel.org/r/20221117035914.2954454-1-cuigaosheng1@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vme/bridges/vme_tsi148.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c
+index 50ae26977a02..5ccda1a363ec 100644
+--- a/drivers/vme/bridges/vme_tsi148.c
++++ b/drivers/vme/bridges/vme_tsi148.c
+@@ -1771,6 +1771,7 @@ static int tsi148_dma_list_add(struct vme_dma_list *list,
+       return 0;
+ err_dma:
++      list_del(&entry->list);
+ err_dest:
+ err_source:
+ err_align:
+-- 
+2.35.1
+
diff --git a/queue-5.10/stmmac-fix-potential-division-by-0.patch b/queue-5.10/stmmac-fix-potential-division-by-0.patch
new file mode 100644 (file)
index 0000000..daac4aa
--- /dev/null
@@ -0,0 +1,89 @@
+From 54250e171bb680ef682d4591f074b78bac03d4a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Dec 2022 23:37:22 +0100
+Subject: stmmac: fix potential division by 0
+
+From: Piergiorgio Beruto <piergiorgio.beruto@gmail.com>
+
+[ Upstream commit ede5a389852d3640a28e7187fb32b7f204380901 ]
+
+When the MAC is connected to a 10 Mb/s PHY and the PTP clock is derived
+from the MAC reference clock (default), the clk_ptp_rate becomes too
+small and the calculated sub second increment becomes 0 when computed by
+the stmmac_config_sub_second_increment() function within
+stmmac_init_tstamp_counter().
+
+Therefore, the subsequent div_u64 in stmmac_init_tstamp_counter()
+operation triggers a divide by 0 exception as shown below.
+
+[   95.062067] socfpga-dwmac ff700000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
+[   95.076440] socfpga-dwmac ff700000.ethernet eth0: PHY [stmmac-0:08] driver [NCN26000] (irq=49)
+[   95.095964] dwmac1000: Master AXI performs any burst length
+[   95.101588] socfpga-dwmac ff700000.ethernet eth0: No Safety Features support found
+[   95.109428] Division by zero in kernel.
+[   95.113447] CPU: 0 PID: 239 Comm: ifconfig Not tainted 6.1.0-rc7-centurion3-1.0.3.0-01574-gb624218205b7-dirty #77
+[   95.123686] Hardware name: Altera SOCFPGA
+[   95.127695]  unwind_backtrace from show_stack+0x10/0x14
+[   95.132938]  show_stack from dump_stack_lvl+0x40/0x4c
+[   95.137992]  dump_stack_lvl from Ldiv0+0x8/0x10
+[   95.142527]  Ldiv0 from __aeabi_uidivmod+0x8/0x18
+[   95.147232]  __aeabi_uidivmod from div_u64_rem+0x1c/0x40
+[   95.152552]  div_u64_rem from stmmac_init_tstamp_counter+0xd0/0x164
+[   95.158826]  stmmac_init_tstamp_counter from stmmac_hw_setup+0x430/0xf00
+[   95.165533]  stmmac_hw_setup from __stmmac_open+0x214/0x2d4
+[   95.171117]  __stmmac_open from stmmac_open+0x30/0x44
+[   95.176182]  stmmac_open from __dev_open+0x11c/0x134
+[   95.181172]  __dev_open from __dev_change_flags+0x168/0x17c
+[   95.186750]  __dev_change_flags from dev_change_flags+0x14/0x50
+[   95.192662]  dev_change_flags from devinet_ioctl+0x2b4/0x604
+[   95.198321]  devinet_ioctl from inet_ioctl+0x1ec/0x214
+[   95.203462]  inet_ioctl from sock_ioctl+0x14c/0x3c4
+[   95.208354]  sock_ioctl from vfs_ioctl+0x20/0x38
+[   95.212984]  vfs_ioctl from sys_ioctl+0x250/0x844
+[   95.217691]  sys_ioctl from ret_fast_syscall+0x0/0x4c
+[   95.222743] Exception stack(0xd0ee1fa8 to 0xd0ee1ff0)
+[   95.227790] 1fa0:                   00574c4f be9aeca4 00000003 00008914 be9aeca4 be9aec50
+[   95.235945] 1fc0: 00574c4f be9aeca4 0059f078 00000036 be9aee8c be9aef7a 00000015 00000000
+[   95.244096] 1fe0: 005a01f0 be9aec38 004d7484 b6e67d74
+
+Signed-off-by: Piergiorgio Beruto <piergiorgio.beruto@gmail.com>
+Fixes: 91a2559c1dc5 ("net: stmmac: Fix sub-second increment")
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/de4c64ccac9084952c56a06a8171d738604c4770.1670678513.git.piergiorgio.beruto@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 3 ++-
+ drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h      | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
+index 53efcc9c40e2..0ad5ce874557 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
+@@ -44,7 +44,8 @@ static void config_sub_second_increment(void __iomem *ioaddr,
+       if (!(value & PTP_TCR_TSCTRLSSR))
+               data = (data * 1000) / 465;
+-      data &= PTP_SSIR_SSINC_MASK;
++      if (data > PTP_SSIR_SSINC_MAX)
++              data = PTP_SSIR_SSINC_MAX;
+       reg_value = data;
+       if (gmac4)
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+index 7abb1d47e7da..60e6b085e2f6 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+@@ -61,7 +61,7 @@
+ #define       PTP_TCR_TSENMACADDR     BIT(18)
+ /* SSIR defines */
+-#define       PTP_SSIR_SSINC_MASK             0xff
++#define       PTP_SSIR_SSINC_MAX              0xff
+ #define       GMAC4_PTP_SSIR_SSINC_SHIFT      16
+ #endif        /* __STMMAC_PTP_H__ */
+-- 
+2.35.1
+
diff --git a/queue-5.10/sunrpc-fix-missing-release-socket-in-rpc_sockname.patch b/queue-5.10/sunrpc-fix-missing-release-socket-in-rpc_sockname.patch
new file mode 100644 (file)
index 0000000..1aaac74
--- /dev/null
@@ -0,0 +1,37 @@
+From 19bf4473fe4c5946968eb643e3319a9471685c1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Nov 2022 17:23:42 +0800
+Subject: SUNRPC: Fix missing release socket in rpc_sockname()
+
+From: Wang ShaoBo <bobo.shaobowang@huawei.com>
+
+[ Upstream commit 50fa355bc0d75911fe9d5072a5ba52cdb803aff7 ]
+
+socket dynamically created is not released when getting an unintended
+address family type in rpc_sockname(), direct to out_release for calling
+sock_release().
+
+Fixes: 2e738fdce22f ("SUNRPC: Add API to acquire source address")
+Signed-off-by: Wang ShaoBo <bobo.shaobowang@huawei.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/clnt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index 78c6648af782..c478108ca6a6 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -1361,7 +1361,7 @@ static int rpc_sockname(struct net *net, struct sockaddr *sap, size_t salen,
+               break;
+       default:
+               err = -EAFNOSUPPORT;
+-              goto out;
++              goto out_release;
+       }
+       if (err < 0) {
+               dprintk("RPC:       can't bind UDP socket (%d)\n", err);
+-- 
+2.35.1
+
diff --git a/queue-5.10/test_firmware-fix-memory-leak-in-test_firmware_init.patch b/queue-5.10/test_firmware-fix-memory-leak-in-test_firmware_init.patch
new file mode 100644 (file)
index 0000000..3929dc7
--- /dev/null
@@ -0,0 +1,54 @@
+From 9ed17e0c8d8b202cbe80558e5b32faba8b104c53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Nov 2022 11:57:21 +0800
+Subject: test_firmware: fix memory leak in test_firmware_init()
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 7610615e8cdb3f6f5bbd9d8e7a5d8a63e3cabf2e ]
+
+When misc_register() failed in test_firmware_init(), the memory pointed
+by test_fw_config->name is not released. The memory leak information is
+as follows:
+unreferenced object 0xffff88810a34cb00 (size 32):
+  comm "insmod", pid 7952, jiffies 4294948236 (age 49.060s)
+  hex dump (first 32 bytes):
+    74 65 73 74 2d 66 69 72 6d 77 61 72 65 2e 62 69  test-firmware.bi
+    6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  n...............
+  backtrace:
+    [<ffffffff81b21fcb>] __kmalloc_node_track_caller+0x4b/0xc0
+    [<ffffffff81affb96>] kstrndup+0x46/0xc0
+    [<ffffffffa0403a49>] __test_firmware_config_init+0x29/0x380 [test_firmware]
+    [<ffffffffa040f068>] 0xffffffffa040f068
+    [<ffffffff81002c41>] do_one_initcall+0x141/0x780
+    [<ffffffff816a72c3>] do_init_module+0x1c3/0x630
+    [<ffffffff816adb9e>] load_module+0x623e/0x76a0
+    [<ffffffff816af471>] __do_sys_finit_module+0x181/0x240
+    [<ffffffff89978f99>] do_syscall_64+0x39/0xb0
+    [<ffffffff89a0008b>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Fixes: c92316bf8e94 ("test_firmware: add batched firmware tests")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Acked-by: Luis Chamberlain <mcgrof@kernel.org>
+Link: https://lore.kernel.org/r/20221119035721.18268-1-shaozhengchao@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/test_firmware.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/lib/test_firmware.c b/lib/test_firmware.c
+index 2baa275a6ddf..76550d2e2edc 100644
+--- a/lib/test_firmware.c
++++ b/lib/test_firmware.c
+@@ -1114,6 +1114,7 @@ static int __init test_firmware_init(void)
+       rc = misc_register(&test_fw_misc_device);
+       if (rc) {
++              __test_firmware_config_free();
+               kfree(test_fw_config);
+               pr_err("could not register misc device: %d\n", rc);
+               return rc;
+-- 
+2.35.1
+
diff --git a/queue-5.10/thermal-drivers-imx8mm_thermal-validate-temperature-.patch b/queue-5.10/thermal-drivers-imx8mm_thermal-validate-temperature-.patch
new file mode 100644 (file)
index 0000000..53a674a
--- /dev/null
@@ -0,0 +1,45 @@
+From 20a47ff622145ebeba1a65fdb42ffbaa394d55ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Oct 2022 09:35:07 +0200
+Subject: thermal/drivers/imx8mm_thermal: Validate temperature range
+
+From: Marcus Folkesson <marcus.folkesson@gmail.com>
+
+[ Upstream commit d37edc7370273306d8747097fafa62436c1cfe16 ]
+
+Check against the upper temperature limit (125 degrees C) before
+consider the temperature valid.
+
+Fixes: 5eed800a6811 ("thermal: imx8mm: Add support for i.MX8MM thermal monitoring unit")
+Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
+Reviewed-by: Jacky Bai <ping.bai@nxp.com>
+Link: https://lore.kernel.org/r/20221014073507.1594844-1-marcus.folkesson@gmail.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/imx8mm_thermal.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c
+index 0f4cabd2a8c6..6be16e0598b6 100644
+--- a/drivers/thermal/imx8mm_thermal.c
++++ b/drivers/thermal/imx8mm_thermal.c
+@@ -65,8 +65,14 @@ static int imx8mm_tmu_get_temp(void *data, int *temp)
+       u32 val;
+       val = readl_relaxed(tmu->base + TRITSR) & TRITSR_TEMP0_VAL_MASK;
++
++      /*
++       * Do not validate against the V bit (bit 31) due to errata
++       * ERR051272: TMU: Bit 31 of registers TMU_TSCR/TMU_TRITSR/TMU_TRATSR invalid
++       */
++
+       *temp = val * 1000;
+-      if (*temp < VER1_TEMP_LOW_LIMIT)
++      if (*temp < VER1_TEMP_LOW_LIMIT || *temp > VER2_TEMP_HIGH_LIMIT)
+               return -EAGAIN;
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/timerqueue-use-rb_entry_safe-in-timerqueue_getnext.patch b/queue-5.10/timerqueue-use-rb_entry_safe-in-timerqueue_getnext.patch
new file mode 100644 (file)
index 0000000..3812729
--- /dev/null
@@ -0,0 +1,44 @@
+From 6a263f440c879a8f6aeafe2ab29173cb7df8d0af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 19:54:23 +0000
+Subject: timerqueue: Use rb_entry_safe() in timerqueue_getnext()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Barnabás Pőcze <pobrn@protonmail.com>
+
+[ Upstream commit 2f117484329b233455ee278f2d9b0a4356835060 ]
+
+When `timerqueue_getnext()` is called on an empty timer queue, it will
+use `rb_entry()` on a NULL pointer, which is invalid. Fix that by using
+`rb_entry_safe()` which handles NULL pointers.
+
+This has not caused any issues so far because the offset of the `rb_node`
+member in `timerqueue_node` is 0, so `rb_entry()` is essentially a no-op.
+
+Fixes: 511885d7061e ("lib/timerqueue: Rely on rbtree semantics for next timer")
+Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20221114195421.342929-1-pobrn@protonmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/timerqueue.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/timerqueue.h b/include/linux/timerqueue.h
+index 93884086f392..adc80e29168e 100644
+--- a/include/linux/timerqueue.h
++++ b/include/linux/timerqueue.h
+@@ -35,7 +35,7 @@ struct timerqueue_node *timerqueue_getnext(struct timerqueue_head *head)
+ {
+       struct rb_node *leftmost = rb_first_cached(&head->rb_root);
+-      return rb_entry(leftmost, struct timerqueue_node, node);
++      return rb_entry_safe(leftmost, struct timerqueue_node, node);
+ }
+ static inline void timerqueue_init(struct timerqueue_node *node)
+-- 
+2.35.1
+
diff --git a/queue-5.10/tpm-tpm_crb-fix-error-message-in-__crb_relinquish_lo.patch b/queue-5.10/tpm-tpm_crb-fix-error-message-in-__crb_relinquish_lo.patch
new file mode 100644 (file)
index 0000000..f4ff8ad
--- /dev/null
@@ -0,0 +1,38 @@
+From 77860f08ff6e41408e3c9b3daf6e500f0b74f4ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 11:38:53 -0800
+Subject: tpm/tpm_crb: Fix error message in __crb_relinquish_locality()
+
+From: Michael Kelley <mikelley@microsoft.com>
+
+[ Upstream commit f5264068071964b56dc02c9dab3d11574aaca6ff ]
+
+The error message in __crb_relinquish_locality() mentions requestAccess
+instead of Relinquish. Fix it.
+
+Fixes: 888d867df441 ("tpm: cmd_ready command can be issued only after granting locality")
+Signed-off-by: Michael Kelley <mikelley@microsoft.com>
+Acked-by: Tomas Winkler <tomas.winkler@intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/tpm/tpm_crb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
+index a9dcf31eadd2..35c5227f3a88 100644
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -252,7 +252,7 @@ static int __crb_relinquish_locality(struct device *dev,
+       iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl);
+       if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, mask, value,
+                                TPM2_TIMEOUT_C)) {
+-              dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n");
++              dev_warn(dev, "TPM_LOC_STATE_x.Relinquish timed out\n");
+               return -ETIME;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/tpm-tpm_ftpm_tee-fix-error-handling-in-ftpm_mod_init.patch b/queue-5.10/tpm-tpm_ftpm_tee-fix-error-handling-in-ftpm_mod_init.patch
new file mode 100644 (file)
index 0000000..0eda6ce
--- /dev/null
@@ -0,0 +1,47 @@
+From 953c9af86762919c067138a1b37fc9dfc4b6be00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Nov 2022 03:19:26 +0000
+Subject: tpm/tpm_ftpm_tee: Fix error handling in ftpm_mod_init()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 2b7d07f7acaac2c7750e420dcf4414588ede6d03 ]
+
+The ftpm_mod_init() returns the driver_register() directly without checking
+its return value, if driver_register() failed, the ftpm_tee_plat_driver is
+not unregistered.
+
+Fix by unregister ftpm_tee_plat_driver when driver_register() failed.
+
+Fixes: 9f1944c23c8c ("tpm_ftpm_tee: register driver on TEE bus")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Reviewed-by: Maxim Uvarov <maxim.uvarov@linaro.org>
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/tpm/tpm_ftpm_tee.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/char/tpm/tpm_ftpm_tee.c b/drivers/char/tpm/tpm_ftpm_tee.c
+index 6e3235565a4d..d9daaafdd295 100644
+--- a/drivers/char/tpm/tpm_ftpm_tee.c
++++ b/drivers/char/tpm/tpm_ftpm_tee.c
+@@ -397,7 +397,13 @@ static int __init ftpm_mod_init(void)
+       if (rc)
+               return rc;
+-      return driver_register(&ftpm_tee_driver.driver);
++      rc = driver_register(&ftpm_tee_driver.driver);
++      if (rc) {
++              platform_driver_unregister(&ftpm_tee_plat_driver);
++              return rc;
++      }
++
++      return 0;
+ }
+ static void __exit ftpm_mod_exit(void)
+-- 
+2.35.1
+
diff --git a/queue-5.10/tracing-hist-fix-issue-of-losting-command-info-in-er.patch b/queue-5.10/tracing-hist-fix-issue-of-losting-command-info-in-er.patch
new file mode 100644 (file)
index 0000000..1dc587f
--- /dev/null
@@ -0,0 +1,93 @@
+From 81bcee2d63fa21e5586ee99532f1f43c2fcc82bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 21:53:26 +0800
+Subject: tracing/hist: Fix issue of losting command info in error_log
+
+From: Zheng Yejian <zhengyejian1@huawei.com>
+
+[ Upstream commit 608c6ed3337850c767ab0dd6c583477922233e29 ]
+
+When input some constructed invalid 'trigger' command, command info
+in 'error_log' are lost [1].
+
+The root cause is that there is a path that event_hist_trigger_parse()
+is recursely called once and 'last_cmd' which save origin command is
+cleared, then later calling of hist_err() will no longer record origin
+command info:
+
+  event_hist_trigger_parse() {
+    last_cmd_set()  // <1> 'last_cmd' save origin command here at first
+    create_actions() {
+      onmatch_create() {
+        action_create() {
+          trace_action_create() {
+            trace_action_create_field_var() {
+              create_field_var_hist() {
+                event_hist_trigger_parse() {  // <2> recursely called once
+                  hist_err_clear()  // <3> 'last_cmd' is cleared here
+                }
+                hist_err()  // <4> No longer find origin command!!!
+
+Since 'glob' is empty string while running into the recurse call, we
+can trickly check it and bypass the call of hist_err_clear() to solve it.
+
+[1]
+ # cd /sys/kernel/tracing
+ # echo "my_synth_event int v1; int v2; int v3;" >> synthetic_events
+ # echo 'hist:keys=pid' >> events/sched/sched_waking/trigger
+ # echo "hist:keys=next_pid:onmatch(sched.sched_waking).my_synth_event(\
+pid,pid1)" >> events/sched/sched_switch/trigger
+ # cat error_log
+[  8.405018] hist:sched:sched_switch: error: Couldn't find synthetic event
+  Command:
+hist:keys=next_pid:onmatch(sched.sched_waking).my_synth_event(pid,pid1)
+                                                          ^
+[  8.816902] hist:sched:sched_switch: error: Couldn't find field
+  Command:
+hist:keys=next_pid:onmatch(sched.sched_waking).my_synth_event(pid,pid1)
+                          ^
+[  8.816902] hist:sched:sched_switch: error: Couldn't parse field variable
+  Command:
+hist:keys=next_pid:onmatch(sched.sched_waking).my_synth_event(pid,pid1)
+                          ^
+[  8.999880] : error: Couldn't find field
+  Command:
+           ^
+[  8.999880] : error: Couldn't parse field variable
+  Command:
+           ^
+[  8.999880] : error: Couldn't find field
+  Command:
+           ^
+[  8.999880] : error: Couldn't create histogram for field
+  Command:
+           ^
+
+Link: https://lore.kernel.org/linux-trace-kernel/20221207135326.3483216-1-zhengyejian1@huawei.com
+
+Cc: <mhiramat@kernel.org>
+Cc: <zanussi@kernel.org>
+Fixes: f404da6e1d46 ("tracing: Add 'last error' error facility for hist triggers")
+Signed-off-by: Zheng Yejian <zhengyejian1@huawei.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_events_hist.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index fd5416829445..8e01ab49118d 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -5827,7 +5827,7 @@ static int event_hist_trigger_func(struct event_command *cmd_ops,
+       /* Just return zero, not the number of registered triggers */
+       ret = 0;
+  out:
+-      if (ret == 0)
++      if (ret == 0 && glob[0])
+               hist_err_clear();
+       return ret;
+-- 
+2.35.1
+
diff --git a/queue-5.10/tty-serial-altera_uart_-r-t-x_chars-need-only-uart_p.patch b/queue-5.10/tty-serial-altera_uart_-r-t-x_chars-need-only-uart_p.patch
new file mode 100644 (file)
index 0000000..5c19ef5
--- /dev/null
@@ -0,0 +1,71 @@
+From 91d5e3e8b18f15ff0dbdeab3937d3c6e2469ce73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Sep 2022 07:20:43 +0200
+Subject: tty: serial: altera_uart_{r,t}x_chars() need only uart_port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+[ Upstream commit 3af44d9bb0539d5fa27d6159d696fda5f3747bff ]
+
+Both altera_uart_{r,t}x_chars() need only uart_port, not altera_uart. So
+pass the former from altera_uart_interrupt() directly.
+
+Apart it maybe saves a dereference, this makes the transition of
+altera_uart_tx_chars() easier to follow in the next patch.
+
+Cc: Tobias Klauser <tklauser@distanz.ch>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Acked-by: Tobias Klauser <tklauser@distanz.ch>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20220920052049.20507-4-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 1307c5d33cce ("serial: altera_uart: fix locking in polling mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/altera_uart.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
+index 508a3c2b7781..20c610440133 100644
+--- a/drivers/tty/serial/altera_uart.c
++++ b/drivers/tty/serial/altera_uart.c
+@@ -199,9 +199,8 @@ static void altera_uart_set_termios(struct uart_port *port,
+        */
+ }
+-static void altera_uart_rx_chars(struct altera_uart *pp)
++static void altera_uart_rx_chars(struct uart_port *port)
+ {
+-      struct uart_port *port = &pp->port;
+       unsigned char ch, flag;
+       unsigned short status;
+@@ -248,9 +247,8 @@ static void altera_uart_rx_chars(struct altera_uart *pp)
+       spin_lock(&port->lock);
+ }
+-static void altera_uart_tx_chars(struct altera_uart *pp)
++static void altera_uart_tx_chars(struct uart_port *port)
+ {
+-      struct uart_port *port = &pp->port;
+       struct circ_buf *xmit = &port->state->xmit;
+       if (port->x_char) {
+@@ -288,9 +286,9 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data)
+       spin_lock(&port->lock);
+       if (isr & ALTERA_UART_STATUS_RRDY_MSK)
+-              altera_uart_rx_chars(pp);
++              altera_uart_rx_chars(port);
+       if (isr & ALTERA_UART_STATUS_TRDY_MSK)
+-              altera_uart_tx_chars(pp);
++              altera_uart_tx_chars(port);
+       spin_unlock(&port->lock);
+       return IRQ_RETVAL(isr);
+-- 
+2.35.1
+
diff --git a/queue-5.10/tty-serial-clean-up-stop-tx-part-in-altera_uart_tx_c.patch b/queue-5.10/tty-serial-clean-up-stop-tx-part-in-altera_uart_tx_c.patch
new file mode 100644 (file)
index 0000000..5459f90
--- /dev/null
@@ -0,0 +1,48 @@
+From f9f2b3d5df00fd3b1d8de7a51747eb4583625b90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Sep 2022 07:20:42 +0200
+Subject: tty: serial: clean up stop-tx part in altera_uart_tx_chars()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+[ Upstream commit d9c128117da41cf4cb0e80ae565b5d3ac79dffac ]
+
+The "stop TX" path in altera_uart_tx_chars() is open-coded, so:
+* use uart_circ_empty() to check if the buffer is empty, and
+* when true, call altera_uart_stop_tx().
+
+Cc: Tobias Klauser <tklauser@distanz.ch>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Acked-by: Tobias Klauser <tklauser@distanz.ch>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20220920052049.20507-3-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 1307c5d33cce ("serial: altera_uart: fix locking in polling mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/altera_uart.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
+index 0e487ce091ac..508a3c2b7781 100644
+--- a/drivers/tty/serial/altera_uart.c
++++ b/drivers/tty/serial/altera_uart.c
+@@ -274,10 +274,8 @@ static void altera_uart_tx_chars(struct altera_uart *pp)
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(port);
+-      if (xmit->head == xmit->tail) {
+-              pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
+-              altera_uart_update_ctrl_reg(pp);
+-      }
++      if (uart_circ_empty(xmit))
++              altera_uart_stop_tx(port);
+ }
+ static irqreturn_t altera_uart_interrupt(int irq, void *data)
+-- 
+2.35.1
+
diff --git a/queue-5.10/udf-avoid-double-brelse-in-udf_rename.patch b/queue-5.10/udf-avoid-double-brelse-in-udf_rename.patch
new file mode 100644 (file)
index 0000000..dde1355
--- /dev/null
@@ -0,0 +1,93 @@
+From 7475698591825284bb81e35a9ba9590e9b9669c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Oct 2022 18:57:41 +0900
+Subject: udf: Avoid double brelse() in udf_rename()
+
+From: Shigeru Yoshida <syoshida@redhat.com>
+
+[ Upstream commit c791730f2554a9ebb8f18df9368dc27d4ebc38c2 ]
+
+syzbot reported a warning like below [1]:
+
+VFS: brelse: Trying to free free buffer
+WARNING: CPU: 2 PID: 7301 at fs/buffer.c:1145 __brelse+0x67/0xa0
+...
+Call Trace:
+ <TASK>
+ invalidate_bh_lru+0x99/0x150
+ smp_call_function_many_cond+0xe2a/0x10c0
+ ? generic_remap_file_range_prep+0x50/0x50
+ ? __brelse+0xa0/0xa0
+ ? __mutex_lock+0x21c/0x12d0
+ ? smp_call_on_cpu+0x250/0x250
+ ? rcu_read_lock_sched_held+0xb/0x60
+ ? lock_release+0x587/0x810
+ ? __brelse+0xa0/0xa0
+ ? generic_remap_file_range_prep+0x50/0x50
+ on_each_cpu_cond_mask+0x3c/0x80
+ blkdev_flush_mapping+0x13a/0x2f0
+ blkdev_put_whole+0xd3/0xf0
+ blkdev_put+0x222/0x760
+ deactivate_locked_super+0x96/0x160
+ deactivate_super+0xda/0x100
+ cleanup_mnt+0x222/0x3d0
+ task_work_run+0x149/0x240
+ ? task_work_cancel+0x30/0x30
+ do_exit+0xb29/0x2a40
+ ? reacquire_held_locks+0x4a0/0x4a0
+ ? do_raw_spin_lock+0x12a/0x2b0
+ ? mm_update_next_owner+0x7c0/0x7c0
+ ? rwlock_bug.part.0+0x90/0x90
+ ? zap_other_threads+0x234/0x2d0
+ do_group_exit+0xd0/0x2a0
+ __x64_sys_exit_group+0x3a/0x50
+ do_syscall_64+0x34/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+The cause of the issue is that brelse() is called on both ofibh.sbh
+and ofibh.ebh by udf_find_entry() when it returns NULL.  However,
+brelse() is called by udf_rename(), too.  So, b_count on buffer_head
+becomes unbalanced.
+
+This patch fixes the issue by not calling brelse() by udf_rename()
+when udf_find_entry() returns NULL.
+
+Link: https://syzkaller.appspot.com/bug?id=8297f45698159c6bca8a1f87dc983667c1a1c851 [1]
+Reported-by: syzbot+7902cd7684bc35306224@syzkaller.appspotmail.com
+Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20221023095741.271430-1-syoshida@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/udf/namei.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/udf/namei.c b/fs/udf/namei.c
+index aff5ca32e4f6..58120d2f265f 100644
+--- a/fs/udf/namei.c
++++ b/fs/udf/namei.c
+@@ -1090,8 +1090,9 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
+               return -EINVAL;
+       ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
+-      if (IS_ERR(ofi)) {
+-              retval = PTR_ERR(ofi);
++      if (!ofi || IS_ERR(ofi)) {
++              if (IS_ERR(ofi))
++                      retval = PTR_ERR(ofi);
+               goto end_rename;
+       }
+@@ -1100,8 +1101,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
+       brelse(ofibh.sbh);
+       tloc = lelb_to_cpu(ocfi.icb.extLocation);
+-      if (!ofi || udf_get_lb_pblock(old_dir->i_sb, &tloc, 0)
+-          != old_inode->i_ino)
++      if (udf_get_lb_pblock(old_dir->i_sb, &tloc, 0) != old_inode->i_ino)
+               goto end_rename;
+       nfi = udf_find_entry(new_dir, &new_dentry->d_name, &nfibh, &ncfi);
+-- 
+2.35.1
+
diff --git a/queue-5.10/uio-uio_dmem_genirq-fix-deadlock-between-irq-config-.patch b/queue-5.10/uio-uio_dmem_genirq-fix-deadlock-between-irq-config-.patch
new file mode 100644 (file)
index 0000000..ecfe1e7
--- /dev/null
@@ -0,0 +1,64 @@
+From 5575db30caccd3466328042c9519a3835bede9a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Sep 2022 19:40:58 -0300
+Subject: uio: uio_dmem_genirq: Fix deadlock between irq config and handling
+
+From: Rafael Mendonca <rafaelmendsr@gmail.com>
+
+[ Upstream commit 118b918018175d9fcd8db667f905012e986cc2c9 ]
+
+This fixes a concurrency issue addressed in commit 34cb27528398 ("UIO: Fix
+concurrency issue"):
+
+  "In a SMP case there was a race condition issue between
+  Uio_pdrv_genirq_irqcontrol() running on one CPU and irq handler on
+  another CPU. Fix it by spin_locking shared resources access inside irq
+  handler."
+
+The implementation of "uio_dmem_genirq" was based on "uio_pdrv_genirq" and
+it is used in a similar manner to the "uio_pdrv_genirq" driver with respect
+to interrupt configuration and handling. At the time "uio_dmem_genirq" was
+merged, both had the same implementation of the 'uio_info' handlers
+irqcontrol() and handler(), thus, both had the same concurrency issue
+mentioned by the above commit. However, the above patch was only applied to
+the "uio_pdrv_genirq" driver.
+
+Split out from commit 34cb27528398 ("UIO: Fix concurrency issue").
+
+Fixes: 0a0c3b5a24bd ("Add new uio device for dynamic memory allocation")
+Signed-off-by: Rafael Mendonca <rafaelmendsr@gmail.com>
+Link: https://lore.kernel.org/r/20220930224100.816175-3-rafaelmendsr@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/uio/uio_dmem_genirq.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
+index 796946bab508..92751737bbea 100644
+--- a/drivers/uio/uio_dmem_genirq.c
++++ b/drivers/uio/uio_dmem_genirq.c
+@@ -110,8 +110,10 @@ static irqreturn_t uio_dmem_genirq_handler(int irq, struct uio_info *dev_info)
+        * remember the state so we can allow user space to enable it later.
+        */
++      spin_lock(&priv->lock);
+       if (!test_and_set_bit(0, &priv->flags))
+               disable_irq_nosync(irq);
++      spin_unlock(&priv->lock);
+       return IRQ_HANDLED;
+ }
+@@ -125,7 +127,8 @@ static int uio_dmem_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on)
+        * in the interrupt controller, but keep track of the
+        * state to prevent per-irq depth damage.
+        *
+-       * Serialize this operation to support multiple tasks.
++       * Serialize this operation to support multiple tasks and concurrency
++       * with irq handler on SMP systems.
+        */
+       spin_lock_irqsave(&priv->lock, flags);
+-- 
+2.35.1
+
diff --git a/queue-5.10/uio-uio_dmem_genirq-fix-missing-unlock-in-irq-config.patch b/queue-5.10/uio-uio_dmem_genirq-fix-missing-unlock-in-irq-config.patch
new file mode 100644 (file)
index 0000000..091f2c8
--- /dev/null
@@ -0,0 +1,127 @@
+From 201e814a064d5deb4601feb848cfe1938d04d73b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Sep 2022 19:40:57 -0300
+Subject: uio: uio_dmem_genirq: Fix missing unlock in irq configuration
+
+From: Rafael Mendonca <rafaelmendsr@gmail.com>
+
+[ Upstream commit 9de255c461d1b3f0242b3ad1450c3323a3e00b34 ]
+
+Commit b74351287d4b ("uio: fix a sleep-in-atomic-context bug in
+uio_dmem_genirq_irqcontrol()") started calling disable_irq() without
+holding the spinlock because it can sleep. However, that fix introduced
+another bug: if interrupt is already disabled and a new disable request
+comes in, then the spinlock is not unlocked:
+
+root@localhost:~# printf '\x00\x00\x00\x00' > /dev/uio0
+root@localhost:~# printf '\x00\x00\x00\x00' > /dev/uio0
+root@localhost:~# [   14.851538] BUG: scheduling while atomic: bash/223/0x00000002
+[   14.851991] Modules linked in: uio_dmem_genirq uio myfpga(OE) bochs drm_vram_helper drm_ttm_helper ttm drm_kms_helper drm snd_pcm ppdev joydev psmouse snd_timer snd e1000fb_sys_fops syscopyarea parport sysfillrect soundcore sysimgblt input_leds pcspkr i2c_piix4 serio_raw floppy evbug qemu_fw_cfg mac_hid pata_acpi ip_tables x_tables autofs4 [last unloaded: parport_pc]
+[   14.854206] CPU: 0 PID: 223 Comm: bash Tainted: G           OE      6.0.0-rc7 #21
+[   14.854786] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+[   14.855664] Call Trace:
+[   14.855861]  <TASK>
+[   14.856025]  dump_stack_lvl+0x4d/0x67
+[   14.856325]  dump_stack+0x14/0x1a
+[   14.856583]  __schedule_bug.cold+0x4b/0x5c
+[   14.856915]  __schedule+0xe81/0x13d0
+[   14.857199]  ? idr_find+0x13/0x20
+[   14.857456]  ? get_work_pool+0x2d/0x50
+[   14.857756]  ? __flush_work+0x233/0x280
+[   14.858068]  ? __schedule+0xa95/0x13d0
+[   14.858307]  ? idr_find+0x13/0x20
+[   14.858519]  ? get_work_pool+0x2d/0x50
+[   14.858798]  schedule+0x6c/0x100
+[   14.859009]  schedule_hrtimeout_range_clock+0xff/0x110
+[   14.859335]  ? tty_write_room+0x1f/0x30
+[   14.859598]  ? n_tty_poll+0x1ec/0x220
+[   14.859830]  ? tty_ldisc_deref+0x1a/0x20
+[   14.860090]  schedule_hrtimeout_range+0x17/0x20
+[   14.860373]  do_select+0x596/0x840
+[   14.860627]  ? __kernel_text_address+0x16/0x50
+[   14.860954]  ? poll_freewait+0xb0/0xb0
+[   14.861235]  ? poll_freewait+0xb0/0xb0
+[   14.861517]  ? rpm_resume+0x49d/0x780
+[   14.861798]  ? common_interrupt+0x59/0xa0
+[   14.862127]  ? asm_common_interrupt+0x2b/0x40
+[   14.862511]  ? __uart_start.isra.0+0x61/0x70
+[   14.862902]  ? __check_object_size+0x61/0x280
+[   14.863255]  core_sys_select+0x1c6/0x400
+[   14.863575]  ? vfs_write+0x1c9/0x3d0
+[   14.863853]  ? vfs_write+0x1c9/0x3d0
+[   14.864121]  ? _copy_from_user+0x45/0x70
+[   14.864526]  do_pselect.constprop.0+0xb3/0xf0
+[   14.864893]  ? do_syscall_64+0x6d/0x90
+[   14.865228]  ? do_syscall_64+0x6d/0x90
+[   14.865556]  __x64_sys_pselect6+0x76/0xa0
+[   14.865906]  do_syscall_64+0x60/0x90
+[   14.866214]  ? syscall_exit_to_user_mode+0x2a/0x50
+[   14.866640]  ? do_syscall_64+0x6d/0x90
+[   14.866972]  ? do_syscall_64+0x6d/0x90
+[   14.867286]  ? do_syscall_64+0x6d/0x90
+[   14.867626]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[...] stripped
+[   14.872959]  </TASK>
+
+('myfpga' is a simple 'uio_dmem_genirq' driver I wrote to test this)
+
+The implementation of "uio_dmem_genirq" was based on "uio_pdrv_genirq" and
+it is used in a similar manner to the "uio_pdrv_genirq" driver with respect
+to interrupt configuration and handling. At the time "uio_dmem_genirq" was
+introduced, both had the same implementation of the 'uio_info' handlers
+irqcontrol() and handler(). Then commit 34cb27528398 ("UIO: Fix concurrency
+issue"), which was only applied to "uio_pdrv_genirq", ended up making them
+a little different. That commit, among other things, changed disable_irq()
+to disable_irq_nosync() in the implementation of irqcontrol(). The
+motivation there was to avoid a deadlock between irqcontrol() and
+handler(), since it added a spinlock in the irq handler, and disable_irq()
+waits for the completion of the irq handler.
+
+By changing disable_irq() to disable_irq_nosync() in irqcontrol(), we also
+avoid the sleeping-while-atomic bug that commit b74351287d4b ("uio: fix a
+sleep-in-atomic-context bug in uio_dmem_genirq_irqcontrol()") was trying to
+fix. Thus, this fixes the missing unlock in irqcontrol() by importing the
+implementation of irqcontrol() handler from the "uio_pdrv_genirq" driver.
+In the end, it reverts commit b74351287d4b ("uio: fix a
+sleep-in-atomic-context bug in uio_dmem_genirq_irqcontrol()") and change
+disable_irq() to disable_irq_nosync().
+
+It is worth noting that this still does not address the concurrency issue
+fixed by commit 34cb27528398 ("UIO: Fix concurrency issue"). It will be
+addressed separately in the next commits.
+
+Split out from commit 34cb27528398 ("UIO: Fix concurrency issue").
+
+Fixes: b74351287d4b ("uio: fix a sleep-in-atomic-context bug in uio_dmem_genirq_irqcontrol()")
+Signed-off-by: Rafael Mendonca <rafaelmendsr@gmail.com>
+Link: https://lore.kernel.org/r/20220930224100.816175-2-rafaelmendsr@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/uio/uio_dmem_genirq.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
+index ec7f66f4555a..796946bab508 100644
+--- a/drivers/uio/uio_dmem_genirq.c
++++ b/drivers/uio/uio_dmem_genirq.c
+@@ -132,13 +132,11 @@ static int uio_dmem_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on)
+       if (irq_on) {
+               if (test_and_clear_bit(0, &priv->flags))
+                       enable_irq(dev_info->irq);
+-              spin_unlock_irqrestore(&priv->lock, flags);
+       } else {
+-              if (!test_and_set_bit(0, &priv->flags)) {
+-                      spin_unlock_irqrestore(&priv->lock, flags);
+-                      disable_irq(dev_info->irq);
+-              }
++              if (!test_and_set_bit(0, &priv->flags))
++                      disable_irq_nosync(dev_info->irq);
+       }
++      spin_unlock_irqrestore(&priv->lock, flags);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/uprobes-x86-allow-to-probe-a-nop-instruction-with-0x.patch b/queue-5.10/uprobes-x86-allow-to-probe-a-nop-instruction-with-0x.patch
new file mode 100644 (file)
index 0000000..40924d5
--- /dev/null
@@ -0,0 +1,53 @@
+From ff65b0284902b04ab9481b3183be40f27e3ed508 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Dec 2022 18:39:33 +0100
+Subject: uprobes/x86: Allow to probe a NOP instruction with 0x66 prefix
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+[ Upstream commit cefa72129e45313655d53a065b8055aaeb01a0c9 ]
+
+Intel ICC -hotpatch inserts 2-byte "0x66 0x90" NOP at the start of each
+function to reserve extra space for hot-patching, and currently it is not
+possible to probe these functions because branch_setup_xol_ops() wrongly
+rejects NOP with REP prefix as it treats them like word-sized branch
+instructions.
+
+Fixes: 250bbd12c2fe ("uprobes/x86: Refuse to attach uprobe to "word-sized" branch insns")
+Reported-by: Seiji Nishikawa <snishika@redhat.com>
+Suggested-by: Denys Vlasenko <dvlasenk@redhat.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Link: https://lore.kernel.org/r/20221204173933.GA31544@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/uprobes.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
+index 138bdb1fd136..9f948b2d26f6 100644
+--- a/arch/x86/kernel/uprobes.c
++++ b/arch/x86/kernel/uprobes.c
+@@ -722,8 +722,9 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
+       switch (opc1) {
+       case 0xeb:      /* jmp 8 */
+       case 0xe9:      /* jmp 32 */
+-      case 0x90:      /* prefix* + nop; same as jmp with .offs = 0 */
+               break;
++      case 0x90:      /* prefix* + nop; same as jmp with .offs = 0 */
++              goto setup;
+       case 0xe8:      /* call relative */
+               branch_clear_offset(auprobe, insn);
+@@ -753,6 +754,7 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
+                       return -ENOTSUPP;
+       }
++setup:
+       auprobe->branch.opc1 = opc1;
+       auprobe->branch.ilen = insn->length;
+       auprobe->branch.offs = insn->immediate.value;
+-- 
+2.35.1
+
diff --git a/queue-5.10/usb-fotg210-udc-fix-ages-old-endianness-issues.patch b/queue-5.10/usb-fotg210-udc-fix-ages-old-endianness-issues.patch
new file mode 100644 (file)
index 0000000..46337b2
--- /dev/null
@@ -0,0 +1,71 @@
+From 75ef27cdd227a087bf7fa8b1c9450ec297e41c19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Nov 2022 10:03:17 +0100
+Subject: usb: fotg210-udc: Fix ages old endianness issues
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 46ed6026ca2181c917c8334a82e3eaf40a6234dd ]
+
+The code in the FOTG210 driver isn't entirely endianness-agnostic
+as reported by the kernel robot sparse testing. This came to
+the surface while moving the files around.
+
+The driver is only used on little-endian systems, so this causes
+no real-world regression, but it is nice to be strict and have
+some compile coverage also on big endian machines, so fix it
+up with the right LE accessors.
+
+Fixes: b84a8dee23fd ("usb: gadget: add Faraday fotg210_udc driver")
+Reported-by: kernel test robot <lkp@intel.com>
+Link: https://lore.kernel.org/linux-usb/202211110910.0dJ7nZCn-lkp@intel.com/
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20221111090317.94228-1-linus.walleij@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/fotg210-udc.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c
+index 75bf446f4a66..11712bc89635 100644
+--- a/drivers/usb/gadget/udc/fotg210-udc.c
++++ b/drivers/usb/gadget/udc/fotg210-udc.c
+@@ -629,10 +629,10 @@ static void fotg210_request_error(struct fotg210_udc *fotg210)
+ static void fotg210_set_address(struct fotg210_udc *fotg210,
+                               struct usb_ctrlrequest *ctrl)
+ {
+-      if (ctrl->wValue >= 0x0100) {
++      if (le16_to_cpu(ctrl->wValue) >= 0x0100) {
+               fotg210_request_error(fotg210);
+       } else {
+-              fotg210_set_dev_addr(fotg210, ctrl->wValue);
++              fotg210_set_dev_addr(fotg210, le16_to_cpu(ctrl->wValue));
+               fotg210_set_cxdone(fotg210);
+       }
+ }
+@@ -713,17 +713,17 @@ static void fotg210_get_status(struct fotg210_udc *fotg210,
+       switch (ctrl->bRequestType & USB_RECIP_MASK) {
+       case USB_RECIP_DEVICE:
+-              fotg210->ep0_data = 1 << USB_DEVICE_SELF_POWERED;
++              fotg210->ep0_data = cpu_to_le16(1 << USB_DEVICE_SELF_POWERED);
+               break;
+       case USB_RECIP_INTERFACE:
+-              fotg210->ep0_data = 0;
++              fotg210->ep0_data = cpu_to_le16(0);
+               break;
+       case USB_RECIP_ENDPOINT:
+               epnum = ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK;
+               if (epnum)
+                       fotg210->ep0_data =
+-                              fotg210_is_epnstall(fotg210->ep[epnum])
+-                              << USB_ENDPOINT_HALT;
++                              cpu_to_le16(fotg210_is_epnstall(fotg210->ep[epnum])
++                                          << USB_ENDPOINT_HALT);
+               else
+                       fotg210_request_error(fotg210);
+               break;
+-- 
+2.35.1
+
diff --git a/queue-5.10/usb-gadget-f_hid-fix-f_hidg-lifetime-vs-cdev.patch b/queue-5.10/usb-gadget-f_hid-fix-f_hidg-lifetime-vs-cdev.patch
new file mode 100644 (file)
index 0000000..3442771
--- /dev/null
@@ -0,0 +1,164 @@
+From 733bec1370fef376d4c06d0198561a239c9aeafd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 12:35:21 +0000
+Subject: usb: gadget: f_hid: fix f_hidg lifetime vs cdev
+
+From: John Keeping <john@metanate.com>
+
+[ Upstream commit 89ff3dfac604614287ad5aad9370c3f984ea3f4b ]
+
+The embedded struct cdev does not have its lifetime correctly tied to
+the enclosing struct f_hidg, so there is a use-after-free if /dev/hidgN
+is held open while the gadget is deleted.
+
+This can readily be replicated with libusbgx's example programs (for
+conciseness - operating directly via configfs is equivalent):
+
+       gadget-hid
+       exec 3<> /dev/hidg0
+       gadget-vid-pid-remove
+       exec 3<&-
+
+Pull the existing device up in to struct f_hidg and make use of the
+cdev_device_{add,del}() helpers.  This changes the lifetime of the
+device object to match struct f_hidg, but note that it is still added
+and deleted at the same time.
+
+Fixes: 71adf1189469 ("USB: gadget: add HID gadget driver")
+Tested-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Reviewed-by: Lee Jones <lee@kernel.org>
+Signed-off-by: John Keeping <john@metanate.com>
+Link: https://lore.kernel.org/r/20221122123523.3068034-2-john@metanate.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_hid.c | 52 ++++++++++++++++-------------
+ 1 file changed, 28 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
+index 8cb199f52b52..97e927eacc62 100644
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -71,7 +71,7 @@ struct f_hidg {
+       wait_queue_head_t               write_queue;
+       struct usb_request              *req;
+-      int                             minor;
++      struct device                   dev;
+       struct cdev                     cdev;
+       struct usb_function             func;
+@@ -84,6 +84,14 @@ static inline struct f_hidg *func_to_hidg(struct usb_function *f)
+       return container_of(f, struct f_hidg, func);
+ }
++static void hidg_release(struct device *dev)
++{
++      struct f_hidg *hidg = container_of(dev, struct f_hidg, dev);
++
++      kfree(hidg->set_report_buf);
++      kfree(hidg);
++}
++
+ /*-------------------------------------------------------------------------*/
+ /*                           Static descriptors                            */
+@@ -904,9 +912,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
+       struct usb_ep           *ep;
+       struct f_hidg           *hidg = func_to_hidg(f);
+       struct usb_string       *us;
+-      struct device           *device;
+       int                     status;
+-      dev_t                   dev;
+       /* maybe allocate device-global string IDs, and patch descriptors */
+       us = usb_gstrings_attach(c->cdev, ct_func_strings,
+@@ -999,21 +1005,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
+       /* create char device */
+       cdev_init(&hidg->cdev, &f_hidg_fops);
+-      dev = MKDEV(major, hidg->minor);
+-      status = cdev_add(&hidg->cdev, dev, 1);
++      status = cdev_device_add(&hidg->cdev, &hidg->dev);
+       if (status)
+               goto fail_free_descs;
+-      device = device_create(hidg_class, NULL, dev, NULL,
+-                             "%s%d", "hidg", hidg->minor);
+-      if (IS_ERR(device)) {
+-              status = PTR_ERR(device);
+-              goto del;
+-      }
+-
+       return 0;
+-del:
+-      cdev_del(&hidg->cdev);
+ fail_free_descs:
+       usb_free_all_descriptors(f);
+ fail:
+@@ -1244,9 +1240,7 @@ static void hidg_free(struct usb_function *f)
+       hidg = func_to_hidg(f);
+       opts = container_of(f->fi, struct f_hid_opts, func_inst);
+-      kfree(hidg->report_desc);
+-      kfree(hidg->set_report_buf);
+-      kfree(hidg);
++      put_device(&hidg->dev);
+       mutex_lock(&opts->lock);
+       --opts->refcnt;
+       mutex_unlock(&opts->lock);
+@@ -1256,8 +1250,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct f_hidg *hidg = func_to_hidg(f);
+-      device_destroy(hidg_class, MKDEV(major, hidg->minor));
+-      cdev_del(&hidg->cdev);
++      cdev_device_del(&hidg->cdev, &hidg->dev);
+       usb_free_all_descriptors(f);
+ }
+@@ -1266,6 +1259,7 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
+ {
+       struct f_hidg *hidg;
+       struct f_hid_opts *opts;
++      int ret;
+       /* allocate and initialize one new instance */
+       hidg = kzalloc(sizeof(*hidg), GFP_KERNEL);
+@@ -1277,17 +1271,27 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
+       mutex_lock(&opts->lock);
+       ++opts->refcnt;
+-      hidg->minor = opts->minor;
++      device_initialize(&hidg->dev);
++      hidg->dev.release = hidg_release;
++      hidg->dev.class = hidg_class;
++      hidg->dev.devt = MKDEV(major, opts->minor);
++      ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor);
++      if (ret) {
++              --opts->refcnt;
++              mutex_unlock(&opts->lock);
++              return ERR_PTR(ret);
++      }
++
+       hidg->bInterfaceSubClass = opts->subclass;
+       hidg->bInterfaceProtocol = opts->protocol;
+       hidg->report_length = opts->report_length;
+       hidg->report_desc_length = opts->report_desc_length;
+       if (opts->report_desc) {
+-              hidg->report_desc = kmemdup(opts->report_desc,
+-                                          opts->report_desc_length,
+-                                          GFP_KERNEL);
++              hidg->report_desc = devm_kmemdup(&hidg->dev, opts->report_desc,
++                                               opts->report_desc_length,
++                                               GFP_KERNEL);
+               if (!hidg->report_desc) {
+-                      kfree(hidg);
++                      put_device(&hidg->dev);
+                       mutex_unlock(&opts->lock);
+                       return ERR_PTR(-ENOMEM);
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.10/usb-gadget-f_hid-fix-refcount-leak-on-error-path.patch b/queue-5.10/usb-gadget-f_hid-fix-refcount-leak-on-error-path.patch
new file mode 100644 (file)
index 0000000..6ccfbdb
--- /dev/null
@@ -0,0 +1,40 @@
+From cde64d068d79e02e7a592a1f13b844e696717812 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 12:35:22 +0000
+Subject: usb: gadget: f_hid: fix refcount leak on error path
+
+From: John Keeping <john@metanate.com>
+
+[ Upstream commit 70a3288a7586526315105c699b687d78cd32559a ]
+
+When failing to allocate report_desc, opts->refcnt has already been
+incremented so it needs to be decremented to avoid leaving the options
+structure permanently locked.
+
+Fixes: 21a9476a7ba8 ("usb: gadget: hid: add configfs support")
+Tested-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Reviewed-by: Lee Jones <lee@kernel.org>
+Signed-off-by: John Keeping <john@metanate.com>
+Link: https://lore.kernel.org/r/20221122123523.3068034-3-john@metanate.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_hid.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
+index 97e927eacc62..e7cf56b13c64 100644
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -1292,6 +1292,7 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
+                                                GFP_KERNEL);
+               if (!hidg->report_desc) {
+                       put_device(&hidg->dev);
++                      --opts->refcnt;
+                       mutex_unlock(&opts->lock);
+                       return ERR_PTR(-ENOMEM);
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.10/usb-gadget-f_hid-optional-setup-set_report-mode.patch b/queue-5.10/usb-gadget-f_hid-optional-setup-set_report-mode.patch
new file mode 100644 (file)
index 0000000..a00d6dd
--- /dev/null
@@ -0,0 +1,508 @@
+From d17350fb2d8886b04d135d8ccf4becb409e4f654 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 Aug 2021 16:40:04 +0300
+Subject: usb: gadget: f_hid: optional SETUP/SET_REPORT mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maxim Devaev <mdevaev@gmail.com>
+
+[ Upstream commit d7428bc26fc767942c38d74b80299bcd4f01e7cb ]
+
+f_hid provides the OUT Endpoint as only way for receiving reports
+from the host. SETUP/SET_REPORT method is not supported, and this causes
+a number of compatibility problems with various host drivers, especially
+in the case of keyboard emulation using f_hid.
+
+  - Some hosts do not support the OUT Endpoint and ignore it,
+    so it becomes impossible for the gadget to receive a report
+    from the host. In the case of a keyboard, the gadget loses
+    the ability to receive the status of the LEDs.
+
+  - Some BIOSes/UEFIs can't work with HID devices with the OUT Endpoint
+    at all. This may be due to their bugs or incomplete implementation
+    of the HID standard.
+    For example, absolutely all Apple UEFIs can't handle the OUT Endpoint
+    if it goes after IN Endpoint in the descriptor and require the reverse
+    order (OUT, IN) which is a violation of the standard.
+    Other hosts either do not initialize gadgets with a descriptor
+    containing the OUT Endpoint completely (like some HP and DELL BIOSes
+    and embedded firmwares like on KVM switches), or initialize them,
+    but will not poll the IN Endpoint.
+
+This patch adds configfs option no_out_endpoint=1 to disable
+the OUT Endpoint and allows f_hid to receive reports from the host
+via SETUP/SET_REPORT.
+
+Previously, there was such a feature in f_hid, but it was replaced
+by the OUT Endpoint [1] in the commit 99c515005857 ("usb: gadget: hidg:
+register OUT INT endpoint for SET_REPORT"). So this patch actually
+returns the removed functionality while making it optional.
+For backward compatibility reasons, the OUT Endpoint mode remains
+the default behaviour.
+
+  - The OUT Endpoint mode provides the report queue and reduces
+    USB overhead (eliminating SETUP routine) on transmitting a report
+    from the host.
+
+  - If the SETUP/SET_REPORT mode is used, there is no report queue,
+    so the userspace will only read last report. For classic HID devices
+    like keyboards this is not a problem, since it's intended to transmit
+    the status of the LEDs and only the last report is important.
+    This mode provides better compatibility with strange and buggy
+    host drivers.
+
+Both modes passed USBCV tests. Checking with the USB protocol analyzer
+also confirmed that everything is working as it should and the new mode
+ensures operability in all of the described cases.
+
+Link: https://www.spinics.net/lists/linux-usb/msg65494.html [1]
+Reviewed-by: Maciej Żenczykowski <zenczykowski@gmail.com>
+Acked-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Maxim Devaev <mdevaev@gmail.com>
+Link: https://lore.kernel.org/r/20210821134004.363217-1-mdevaev@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 89ff3dfac604 ("usb: gadget: f_hid: fix f_hidg lifetime vs cdev")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_hid.c | 220 +++++++++++++++++++++++-----
+ drivers/usb/gadget/function/u_hid.h |   1 +
+ 2 files changed, 188 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
+index 6742271cd6e6..8cb199f52b52 100644
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -45,12 +45,25 @@ struct f_hidg {
+       unsigned short                  report_desc_length;
+       char                            *report_desc;
+       unsigned short                  report_length;
++      /*
++       * use_out_ep - if true, the OUT Endpoint (interrupt out method)
++       *              will be used to receive reports from the host
++       *              using functions with the "intout" suffix.
++       *              Otherwise, the OUT Endpoint will not be configured
++       *              and the SETUP/SET_REPORT method ("ssreport" suffix)
++       *              will be used to receive reports.
++       */
++      bool                            use_out_ep;
+       /* recv report */
+-      struct list_head                completed_out_req;
+       spinlock_t                      read_spinlock;
+       wait_queue_head_t               read_queue;
++      /* recv report - interrupt out only (use_out_ep == 1) */
++      struct list_head                completed_out_req;
+       unsigned int                    qlen;
++      /* recv report - setup set_report only (use_out_ep == 0) */
++      char                            *set_report_buf;
++      unsigned int                    set_report_length;
+       /* send report */
+       spinlock_t                      write_spinlock;
+@@ -79,7 +92,7 @@ static struct usb_interface_descriptor hidg_interface_desc = {
+       .bDescriptorType        = USB_DT_INTERFACE,
+       /* .bInterfaceNumber    = DYNAMIC */
+       .bAlternateSetting      = 0,
+-      .bNumEndpoints          = 2,
++      /* .bNumEndpoints       = DYNAMIC (depends on use_out_ep) */
+       .bInterfaceClass        = USB_CLASS_HID,
+       /* .bInterfaceSubClass  = DYNAMIC */
+       /* .bInterfaceProtocol  = DYNAMIC */
+@@ -140,7 +153,7 @@ static struct usb_ss_ep_comp_descriptor hidg_ss_out_comp_desc = {
+       /* .wBytesPerInterval   = DYNAMIC */
+ };
+-static struct usb_descriptor_header *hidg_ss_descriptors[] = {
++static struct usb_descriptor_header *hidg_ss_descriptors_intout[] = {
+       (struct usb_descriptor_header *)&hidg_interface_desc,
+       (struct usb_descriptor_header *)&hidg_desc,
+       (struct usb_descriptor_header *)&hidg_ss_in_ep_desc,
+@@ -150,6 +163,14 @@ static struct usb_descriptor_header *hidg_ss_descriptors[] = {
+       NULL,
+ };
++static struct usb_descriptor_header *hidg_ss_descriptors_ssreport[] = {
++      (struct usb_descriptor_header *)&hidg_interface_desc,
++      (struct usb_descriptor_header *)&hidg_desc,
++      (struct usb_descriptor_header *)&hidg_ss_in_ep_desc,
++      (struct usb_descriptor_header *)&hidg_ss_in_comp_desc,
++      NULL,
++};
++
+ /* High-Speed Support */
+ static struct usb_endpoint_descriptor hidg_hs_in_ep_desc = {
+@@ -176,7 +197,7 @@ static struct usb_endpoint_descriptor hidg_hs_out_ep_desc = {
+                                     */
+ };
+-static struct usb_descriptor_header *hidg_hs_descriptors[] = {
++static struct usb_descriptor_header *hidg_hs_descriptors_intout[] = {
+       (struct usb_descriptor_header *)&hidg_interface_desc,
+       (struct usb_descriptor_header *)&hidg_desc,
+       (struct usb_descriptor_header *)&hidg_hs_in_ep_desc,
+@@ -184,6 +205,13 @@ static struct usb_descriptor_header *hidg_hs_descriptors[] = {
+       NULL,
+ };
++static struct usb_descriptor_header *hidg_hs_descriptors_ssreport[] = {
++      (struct usb_descriptor_header *)&hidg_interface_desc,
++      (struct usb_descriptor_header *)&hidg_desc,
++      (struct usb_descriptor_header *)&hidg_hs_in_ep_desc,
++      NULL,
++};
++
+ /* Full-Speed Support */
+ static struct usb_endpoint_descriptor hidg_fs_in_ep_desc = {
+@@ -210,7 +238,7 @@ static struct usb_endpoint_descriptor hidg_fs_out_ep_desc = {
+                                      */
+ };
+-static struct usb_descriptor_header *hidg_fs_descriptors[] = {
++static struct usb_descriptor_header *hidg_fs_descriptors_intout[] = {
+       (struct usb_descriptor_header *)&hidg_interface_desc,
+       (struct usb_descriptor_header *)&hidg_desc,
+       (struct usb_descriptor_header *)&hidg_fs_in_ep_desc,
+@@ -218,6 +246,13 @@ static struct usb_descriptor_header *hidg_fs_descriptors[] = {
+       NULL,
+ };
++static struct usb_descriptor_header *hidg_fs_descriptors_ssreport[] = {
++      (struct usb_descriptor_header *)&hidg_interface_desc,
++      (struct usb_descriptor_header *)&hidg_desc,
++      (struct usb_descriptor_header *)&hidg_fs_in_ep_desc,
++      NULL,
++};
++
+ /*-------------------------------------------------------------------------*/
+ /*                                 Strings                                 */
+@@ -241,8 +276,8 @@ static struct usb_gadget_strings *ct_func_strings[] = {
+ /*-------------------------------------------------------------------------*/
+ /*                              Char Device                                */
+-static ssize_t f_hidg_read(struct file *file, char __user *buffer,
+-                      size_t count, loff_t *ptr)
++static ssize_t f_hidg_intout_read(struct file *file, char __user *buffer,
++                                size_t count, loff_t *ptr)
+ {
+       struct f_hidg *hidg = file->private_data;
+       struct f_hidg_req_list *list;
+@@ -255,15 +290,15 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer,
+       spin_lock_irqsave(&hidg->read_spinlock, flags);
+-#define READ_COND (!list_empty(&hidg->completed_out_req))
++#define READ_COND_INTOUT (!list_empty(&hidg->completed_out_req))
+       /* wait for at least one buffer to complete */
+-      while (!READ_COND) {
++      while (!READ_COND_INTOUT) {
+               spin_unlock_irqrestore(&hidg->read_spinlock, flags);
+               if (file->f_flags & O_NONBLOCK)
+                       return -EAGAIN;
+-              if (wait_event_interruptible(hidg->read_queue, READ_COND))
++              if (wait_event_interruptible(hidg->read_queue, READ_COND_INTOUT))
+                       return -ERESTARTSYS;
+               spin_lock_irqsave(&hidg->read_spinlock, flags);
+@@ -313,6 +348,60 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer,
+       return count;
+ }
++#define READ_COND_SSREPORT (hidg->set_report_buf != NULL)
++
++static ssize_t f_hidg_ssreport_read(struct file *file, char __user *buffer,
++                                  size_t count, loff_t *ptr)
++{
++      struct f_hidg *hidg = file->private_data;
++      char *tmp_buf = NULL;
++      unsigned long flags;
++
++      if (!count)
++              return 0;
++
++      spin_lock_irqsave(&hidg->read_spinlock, flags);
++
++      while (!READ_COND_SSREPORT) {
++              spin_unlock_irqrestore(&hidg->read_spinlock, flags);
++              if (file->f_flags & O_NONBLOCK)
++                      return -EAGAIN;
++
++              if (wait_event_interruptible(hidg->read_queue, READ_COND_SSREPORT))
++                      return -ERESTARTSYS;
++
++              spin_lock_irqsave(&hidg->read_spinlock, flags);
++      }
++
++      count = min_t(unsigned int, count, hidg->set_report_length);
++      tmp_buf = hidg->set_report_buf;
++      hidg->set_report_buf = NULL;
++
++      spin_unlock_irqrestore(&hidg->read_spinlock, flags);
++
++      if (tmp_buf != NULL) {
++              count -= copy_to_user(buffer, tmp_buf, count);
++              kfree(tmp_buf);
++      } else {
++              count = -ENOMEM;
++      }
++
++      wake_up(&hidg->read_queue);
++
++      return count;
++}
++
++static ssize_t f_hidg_read(struct file *file, char __user *buffer,
++                         size_t count, loff_t *ptr)
++{
++      struct f_hidg *hidg = file->private_data;
++
++      if (hidg->use_out_ep)
++              return f_hidg_intout_read(file, buffer, count, ptr);
++      else
++              return f_hidg_ssreport_read(file, buffer, count, ptr);
++}
++
+ static void f_hidg_req_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+       struct f_hidg *hidg = (struct f_hidg *)ep->driver_data;
+@@ -433,14 +522,20 @@ static __poll_t f_hidg_poll(struct file *file, poll_table *wait)
+       if (WRITE_COND)
+               ret |= EPOLLOUT | EPOLLWRNORM;
+-      if (READ_COND)
+-              ret |= EPOLLIN | EPOLLRDNORM;
++      if (hidg->use_out_ep) {
++              if (READ_COND_INTOUT)
++                      ret |= EPOLLIN | EPOLLRDNORM;
++      } else {
++              if (READ_COND_SSREPORT)
++                      ret |= EPOLLIN | EPOLLRDNORM;
++      }
+       return ret;
+ }
+ #undef WRITE_COND
+-#undef READ_COND
++#undef READ_COND_SSREPORT
++#undef READ_COND_INTOUT
+ static int f_hidg_release(struct inode *inode, struct file *fd)
+ {
+@@ -467,7 +562,7 @@ static inline struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep,
+       return alloc_ep_req(ep, length);
+ }
+-static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req)
++static void hidg_intout_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+       struct f_hidg *hidg = (struct f_hidg *) req->context;
+       struct usb_composite_dev *cdev = hidg->func.config->cdev;
+@@ -502,6 +597,37 @@ static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req)
+       }
+ }
++static void hidg_ssreport_complete(struct usb_ep *ep, struct usb_request *req)
++{
++      struct f_hidg *hidg = (struct f_hidg *)req->context;
++      struct usb_composite_dev *cdev = hidg->func.config->cdev;
++      char *new_buf = NULL;
++      unsigned long flags;
++
++      if (req->status != 0 || req->buf == NULL || req->actual == 0) {
++              ERROR(cdev,
++                    "%s FAILED: status=%d, buf=%p, actual=%d\n",
++                    __func__, req->status, req->buf, req->actual);
++              return;
++      }
++
++      spin_lock_irqsave(&hidg->read_spinlock, flags);
++
++      new_buf = krealloc(hidg->set_report_buf, req->actual, GFP_ATOMIC);
++      if (new_buf == NULL) {
++              spin_unlock_irqrestore(&hidg->read_spinlock, flags);
++              return;
++      }
++      hidg->set_report_buf = new_buf;
++
++      hidg->set_report_length = req->actual;
++      memcpy(hidg->set_report_buf, req->buf, req->actual);
++
++      spin_unlock_irqrestore(&hidg->read_spinlock, flags);
++
++      wake_up(&hidg->read_queue);
++}
++
+ static int hidg_setup(struct usb_function *f,
+               const struct usb_ctrlrequest *ctrl)
+ {
+@@ -549,7 +675,11 @@ static int hidg_setup(struct usb_function *f,
+       case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
+                 | HID_REQ_SET_REPORT):
+               VDBG(cdev, "set_report | wLength=%d\n", ctrl->wLength);
+-              goto stall;
++              if (hidg->use_out_ep)
++                      goto stall;
++              req->complete = hidg_ssreport_complete;
++              req->context  = hidg;
++              goto respond;
+               break;
+       case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
+@@ -637,15 +767,18 @@ static void hidg_disable(struct usb_function *f)
+       unsigned long flags;
+       usb_ep_disable(hidg->in_ep);
+-      usb_ep_disable(hidg->out_ep);
+-      spin_lock_irqsave(&hidg->read_spinlock, flags);
+-      list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) {
+-              free_ep_req(hidg->out_ep, list->req);
+-              list_del(&list->list);
+-              kfree(list);
++      if (hidg->out_ep) {
++              usb_ep_disable(hidg->out_ep);
++
++              spin_lock_irqsave(&hidg->read_spinlock, flags);
++              list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) {
++                      free_ep_req(hidg->out_ep, list->req);
++                      list_del(&list->list);
++                      kfree(list);
++              }
++              spin_unlock_irqrestore(&hidg->read_spinlock, flags);
+       }
+-      spin_unlock_irqrestore(&hidg->read_spinlock, flags);
+       spin_lock_irqsave(&hidg->write_spinlock, flags);
+       if (!hidg->write_pending) {
+@@ -691,8 +824,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+               }
+       }
+-
+-      if (hidg->out_ep != NULL) {
++      if (hidg->use_out_ep && hidg->out_ep != NULL) {
+               /* restart endpoint */
+               usb_ep_disable(hidg->out_ep);
+@@ -717,7 +849,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+                                       hidg_alloc_ep_req(hidg->out_ep,
+                                                         hidg->report_length);
+                       if (req) {
+-                              req->complete = hidg_set_report_complete;
++                              req->complete = hidg_intout_complete;
+                               req->context  = hidg;
+                               status = usb_ep_queue(hidg->out_ep, req,
+                                                     GFP_ATOMIC);
+@@ -743,7 +875,8 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+       }
+       return 0;
+ disable_out_ep:
+-      usb_ep_disable(hidg->out_ep);
++      if (hidg->out_ep)
++              usb_ep_disable(hidg->out_ep);
+ free_req_in:
+       if (req_in)
+               free_ep_req(hidg->in_ep, req_in);
+@@ -795,14 +928,21 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
+               goto fail;
+       hidg->in_ep = ep;
+-      ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc);
+-      if (!ep)
+-              goto fail;
+-      hidg->out_ep = ep;
++      hidg->out_ep = NULL;
++      if (hidg->use_out_ep) {
++              ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc);
++              if (!ep)
++                      goto fail;
++              hidg->out_ep = ep;
++      }
++
++      /* used only if use_out_ep == 1 */
++      hidg->set_report_buf = NULL;
+       /* set descriptor dynamic values */
+       hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
+       hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
++      hidg_interface_desc.bNumEndpoints = hidg->use_out_ep ? 2 : 1;
+       hidg->protocol = HID_REPORT_PROTOCOL;
+       hidg->idle = 1;
+       hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
+@@ -833,9 +973,19 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
+       hidg_ss_out_ep_desc.bEndpointAddress =
+               hidg_fs_out_ep_desc.bEndpointAddress;
+-      status = usb_assign_descriptors(f, hidg_fs_descriptors,
+-                      hidg_hs_descriptors, hidg_ss_descriptors,
+-                      hidg_ss_descriptors);
++      if (hidg->use_out_ep)
++              status = usb_assign_descriptors(f,
++                      hidg_fs_descriptors_intout,
++                      hidg_hs_descriptors_intout,
++                      hidg_ss_descriptors_intout,
++                      hidg_ss_descriptors_intout);
++      else
++              status = usb_assign_descriptors(f,
++                      hidg_fs_descriptors_ssreport,
++                      hidg_hs_descriptors_ssreport,
++                      hidg_ss_descriptors_ssreport,
++                      hidg_ss_descriptors_ssreport);
++
+       if (status)
+               goto fail;
+@@ -950,6 +1100,7 @@ CONFIGFS_ATTR(f_hid_opts_, name)
+ F_HID_OPT(subclass, 8, 255);
+ F_HID_OPT(protocol, 8, 255);
++F_HID_OPT(no_out_endpoint, 8, 1);
+ F_HID_OPT(report_length, 16, 65535);
+ static ssize_t f_hid_opts_report_desc_show(struct config_item *item, char *page)
+@@ -1009,6 +1160,7 @@ CONFIGFS_ATTR_RO(f_hid_opts_, dev);
+ static struct configfs_attribute *hid_attrs[] = {
+       &f_hid_opts_attr_subclass,
+       &f_hid_opts_attr_protocol,
++      &f_hid_opts_attr_no_out_endpoint,
+       &f_hid_opts_attr_report_length,
+       &f_hid_opts_attr_report_desc,
+       &f_hid_opts_attr_dev,
+@@ -1093,6 +1245,7 @@ static void hidg_free(struct usb_function *f)
+       hidg = func_to_hidg(f);
+       opts = container_of(f->fi, struct f_hid_opts, func_inst);
+       kfree(hidg->report_desc);
++      kfree(hidg->set_report_buf);
+       kfree(hidg);
+       mutex_lock(&opts->lock);
+       --opts->refcnt;
+@@ -1139,6 +1292,7 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
+                       return ERR_PTR(-ENOMEM);
+               }
+       }
++      hidg->use_out_ep = !opts->no_out_endpoint;
+       mutex_unlock(&opts->lock);
+diff --git a/drivers/usb/gadget/function/u_hid.h b/drivers/usb/gadget/function/u_hid.h
+index 84e6da302499..fa631f34bb3d 100644
+--- a/drivers/usb/gadget/function/u_hid.h
++++ b/drivers/usb/gadget/function/u_hid.h
+@@ -20,6 +20,7 @@ struct f_hid_opts {
+       int                             minor;
+       unsigned char                   subclass;
+       unsigned char                   protocol;
++      unsigned char                   no_out_endpoint;
+       unsigned short                  report_length;
+       unsigned short                  report_desc_length;
+       unsigned char                   *report_desc;
+-- 
+2.35.1
+
diff --git a/queue-5.10/usb-musb-remove-extra-check-in-musb_gadget_vbus_draw.patch b/queue-5.10/usb-musb-remove-extra-check-in-musb_gadget_vbus_draw.patch
new file mode 100644 (file)
index 0000000..417370a
--- /dev/null
@@ -0,0 +1,47 @@
+From 3983e992a62179c1c9d72614f7a09c4ba7c9475e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Nov 2022 20:21:15 +0200
+Subject: usb: musb: remove extra check in musb_gadget_vbus_draw
+
+From: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
+
+[ Upstream commit ecec4b20d29c3d6922dafe7d2555254a454272d2 ]
+
+The checks for musb->xceiv and musb->xceiv->set_power duplicate those in
+usb_phy_set_power(), so there is no need of them. Moreover, not calling
+usb_phy_set_power() results in usb_phy_set_charger_current() not being
+called, so current USB config max current is not propagated through USB
+charger framework and charger drivers may try to draw more current than
+allowed or possible.
+
+Fix that by removing those extra checks and calling usb_phy_set_power()
+directly.
+
+Tested on Motorola Droid4 and Nokia N900
+
+Fixes: a9081a008f84 ("usb: phy: Add USB charger support")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
+Link: https://lore.kernel.org/r/1669400475-4762-1-git-send-email-ivo.g.dimitrov.75@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/musb/musb_gadget.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
+index c273eee35aaa..8dc657c71541 100644
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -1628,8 +1628,6 @@ static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
+ {
+       struct musb     *musb = gadget_to_musb(gadget);
+-      if (!musb->xceiv->set_power)
+-              return -EOPNOTSUPP;
+       return usb_phy_set_power(musb->xceiv, mA);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/usb-roles-fix-of-node-refcount-leak-in-usb_role_swit.patch b/queue-5.10/usb-roles-fix-of-node-refcount-leak-in-usb_role_swit.patch
new file mode 100644 (file)
index 0000000..32c46f9
--- /dev/null
@@ -0,0 +1,51 @@
+From 714ecc59ce11738402e8dc46a4192fcdf5c4face Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 19:12:26 +0800
+Subject: usb: roles: fix of node refcount leak in usb_role_switch_is_parent()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 1ab30c610630da5391a373cddb8a065bf4c4bc01 ]
+
+I got the following report while doing device(mt6370-tcpc) load
+test with CONFIG_OF_UNITTEST and CONFIG_OF_DYNAMIC enabled:
+
+  OF: ERROR: memory leak, expected refcount 1 instead of 2,
+  of_node_get()/of_node_put() unbalanced - destroy cset entry:
+  attach overlay node /i2c/pmic@34
+
+The 'parent' returned by fwnode_get_parent() with refcount incremented.
+it needs be put after using.
+
+Fixes: 6fadd72943b8 ("usb: roles: get usb-role-switch from parent")
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221122111226.251588-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/roles/class.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
+index 33b637d0d8d9..5cc20275335d 100644
+--- a/drivers/usb/roles/class.c
++++ b/drivers/usb/roles/class.c
+@@ -106,10 +106,13 @@ usb_role_switch_is_parent(struct fwnode_handle *fwnode)
+       struct fwnode_handle *parent = fwnode_get_parent(fwnode);
+       struct device *dev;
+-      if (!parent || !fwnode_property_present(parent, "usb-role-switch"))
++      if (!fwnode_property_present(parent, "usb-role-switch")) {
++              fwnode_handle_put(parent);
+               return NULL;
++      }
+       dev = class_find_device_by_fwnode(role_class, parent);
++      fwnode_handle_put(parent);
+       return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/usb-storage-add-check-for-kcalloc.patch b/queue-5.10/usb-storage-add-check-for-kcalloc.patch
new file mode 100644 (file)
index 0000000..e7f3308
--- /dev/null
@@ -0,0 +1,39 @@
+From 268fd6ab433e99bc2a4e9563dd11d7dbd4a1448f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 19:00:58 +0800
+Subject: usb: storage: Add check for kcalloc
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit c35ca10f53c51eeb610d3f8fbc6dd6d511b58a58 ]
+
+As kcalloc may return NULL pointer, the return value should
+be checked and return error if fails as same as the ones in
+alauda_read_map.
+
+Fixes: e80b0fade09e ("[PATCH] USB Storage: add alauda support")
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20221208110058.12983-1-jiasheng@iscas.ac.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/storage/alauda.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
+index 20b857e97e60..7e4ce0e7e05a 100644
+--- a/drivers/usb/storage/alauda.c
++++ b/drivers/usb/storage/alauda.c
+@@ -438,6 +438,8 @@ static int alauda_init_media(struct us_data *us)
+               + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift);
+       MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
+       MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
++      if (MEDIA_INFO(us).pba_to_lba == NULL || MEDIA_INFO(us).lba_to_pba == NULL)
++              return USB_STOR_TRANSPORT_ERROR;
+       if (alauda_reset_media(us) != USB_STOR_XFER_GOOD)
+               return USB_STOR_TRANSPORT_ERROR;
+-- 
+2.35.1
+
diff --git a/queue-5.10/usb-typec-check-for-ops-exit-instead-of-ops-enter-in.patch b/queue-5.10/usb-typec-check-for-ops-exit-instead-of-ops-enter-in.patch
new file mode 100644 (file)
index 0000000..30c5691
--- /dev/null
@@ -0,0 +1,39 @@
+From 17b72e56369ef5ac696778257ee929c364f08a21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 17:59:24 +0100
+Subject: usb: typec: Check for ops->exit instead of ops->enter in altmode_exit
+
+From: Sven Peter <sven@svenpeter.dev>
+
+[ Upstream commit b6ddd180e3d9f92c1e482b3cdeec7dda086b1341 ]
+
+typec_altmode_exit checks if ops->enter is not NULL but then calls
+ops->exit a few lines below. Fix that and check for the function
+pointer it's about to call instead.
+
+Fixes: 8a37d87d72f0 ("usb: typec: Bus type for alternate modes")
+Signed-off-by: Sven Peter <sven@svenpeter.dev>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20221114165924.33487-1-sven@svenpeter.dev
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/bus.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
+index e8ddb81cb6df..f4e7f4d78b56 100644
+--- a/drivers/usb/typec/bus.c
++++ b/drivers/usb/typec/bus.c
+@@ -132,7 +132,7 @@ int typec_altmode_exit(struct typec_altmode *adev)
+       if (!adev || !adev->active)
+               return 0;
+-      if (!pdev->ops || !pdev->ops->enter)
++      if (!pdev->ops || !pdev->ops->exit)
+               return -EOPNOTSUPP;
+       /* Moving to USB Safe State */
+-- 
+2.35.1
+
diff --git a/queue-5.10/usb-typec-tcpci-fix-of-node-refcount-leak-in-tcpci_r.patch b/queue-5.10/usb-typec-tcpci-fix-of-node-refcount-leak-in-tcpci_r.patch
new file mode 100644 (file)
index 0000000..5c0dfde
--- /dev/null
@@ -0,0 +1,60 @@
+From 22678fbbe171ea5a4bbaade3b00322a793608f8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 14:24:16 +0800
+Subject: usb: typec: tcpci: fix of node refcount leak in tcpci_register_port()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 0384e87e3fec735e47f1c133c796f32ef7a72a9b ]
+
+I got the following report while doing device(mt6370-tcpc) load
+test with CONFIG_OF_UNITTEST and CONFIG_OF_DYNAMIC enabled:
+
+  OF: ERROR: memory leak, expected refcount 1 instead of 2,
+  of_node_get()/of_node_put() unbalanced - destroy cset entry:
+  attach overlay node /i2c/pmic@34/tcpc/connector
+
+The 'fwnode' set in tcpci_parse_config() which is called
+in tcpci_register_port(), its node refcount is increased
+in device_get_named_child_node(). It needs be put while
+exiting, so call fwnode_handle_put() in the error path of
+tcpci_register_port() and in tcpci_unregister_port() to
+avoid leak.
+
+Fixes: 5e85a04c8c0d ("usb: typec: add fwnode to tcpc")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20221121062416.1026192-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/tcpm/tcpci.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
+index 49420e28a1f7..069affa5cb1e 100644
+--- a/drivers/usb/typec/tcpm/tcpci.c
++++ b/drivers/usb/typec/tcpm/tcpci.c
+@@ -649,8 +649,10 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data)
+               return ERR_PTR(err);
+       tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc);
+-      if (IS_ERR(tcpci->port))
++      if (IS_ERR(tcpci->port)) {
++              fwnode_handle_put(tcpci->tcpc.fwnode);
+               return ERR_CAST(tcpci->port);
++      }
+       return tcpci;
+ }
+@@ -659,6 +661,7 @@ EXPORT_SYMBOL_GPL(tcpci_register_port);
+ void tcpci_unregister_port(struct tcpci *tcpci)
+ {
+       tcpm_unregister_port(tcpci->port);
++      fwnode_handle_put(tcpci->tcpc.fwnode);
+ }
+ EXPORT_SYMBOL_GPL(tcpci_unregister_port);
+-- 
+2.35.1
+
diff --git a/queue-5.10/usb-typec-tipd-fix-spurious-fwnode_handle_put-in-err.patch b/queue-5.10/usb-typec-tipd-fix-spurious-fwnode_handle_put-in-err.patch
new file mode 100644 (file)
index 0000000..2dd96ec
--- /dev/null
@@ -0,0 +1,47 @@
+From 84065b17ac5d3e9651b0cdb2adafa521371e783d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 18:44:47 +0100
+Subject: usb: typec: tipd: Fix spurious fwnode_handle_put in error path
+
+From: Sven Peter <sven@svenpeter.dev>
+
+[ Upstream commit 782c70edc4852a5d39be12377a85501546236212 ]
+
+The err_role_put error path always calls fwnode_handle_put to release
+the fwnode. This path can be reached after probe itself has already
+released that fwnode though. Fix that by moving fwnode_handle_put in the
+happy path to the very end.
+
+Fixes: 18a6c866bb19 ("usb: typec: tps6598x: Add USB role switching logic")
+Signed-off-by: Sven Peter <sven@svenpeter.dev>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20221114174449.34634-2-sven@svenpeter.dev
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/tps6598x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/typec/tps6598x.c b/drivers/usb/typec/tps6598x.c
+index 6cb5c8e2c853..4722b7f7a4a2 100644
+--- a/drivers/usb/typec/tps6598x.c
++++ b/drivers/usb/typec/tps6598x.c
+@@ -564,7 +564,6 @@ static int tps6598x_probe(struct i2c_client *client)
+               ret = PTR_ERR(tps->port);
+               goto err_role_put;
+       }
+-      fwnode_handle_put(fwnode);
+       if (status & TPS_STATUS_PLUG_PRESENT) {
+               ret = tps6598x_connect(tps, status);
+@@ -583,6 +582,7 @@ static int tps6598x_probe(struct i2c_client *client)
+       }
+       i2c_set_clientdata(client, tps);
++      fwnode_handle_put(fwnode);
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/venus-pm_helpers-fix-error-check-in-vcodec_domains_g.patch b/queue-5.10/venus-pm_helpers-fix-error-check-in-vcodec_domains_g.patch
new file mode 100644 (file)
index 0000000..2b4c5e7
--- /dev/null
@@ -0,0 +1,38 @@
+From 9cbf2996e396df8ee4da5951e1ec1023c3448ae5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Sep 2022 14:37:00 +0800
+Subject: venus: pm_helpers: Fix error check in vcodec_domains_get()
+
+From: Tang Bin <tangbin@cmss.chinamobile.com>
+
+[ Upstream commit 0f6e8d8c94a82e85e1b9b62a7671990740dc6f70 ]
+
+In the function vcodec_domains_get(), dev_pm_domain_attach_by_name()
+may return NULL in some cases, so IS_ERR() doesn't meet the
+requirements. Thus fix it.
+
+Fixes: 7482a983dea3 ("media: venus: redesign clocks and pm domains control")
+Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/pm_helpers.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
+index 710f9a2b132b..f7de02352f1b 100644
+--- a/drivers/media/platform/qcom/venus/pm_helpers.c
++++ b/drivers/media/platform/qcom/venus/pm_helpers.c
+@@ -764,8 +764,8 @@ static int vcodec_domains_get(struct venus_core *core)
+       for (i = 0; i < res->vcodec_pmdomains_num; i++) {
+               pd = dev_pm_domain_attach_by_name(dev,
+                                                 res->vcodec_pmdomains[i]);
+-              if (IS_ERR(pd))
+-                      return PTR_ERR(pd);
++              if (IS_ERR_OR_NULL(pd))
++                      return PTR_ERR(pd) ? : -ENODATA;
+               core->pmdomains[i] = pd;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/vfio-platform-do-not-pass-return-buffer-to-acpi-_rst.patch b/queue-5.10/vfio-platform-do-not-pass-return-buffer-to-acpi-_rst.patch
new file mode 100644 (file)
index 0000000..92fa2fa
--- /dev/null
@@ -0,0 +1,43 @@
+From ba529d73fec87dc84488662b8a43097a0d2de112 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 12:28:25 -0300
+Subject: vfio: platform: Do not pass return buffer to ACPI _RST method
+
+From: Rafael Mendonca <rafaelmendsr@gmail.com>
+
+[ Upstream commit e67e070632a665c932d534b8b800477bb3111449 ]
+
+The ACPI _RST method has no return value, there's no need to pass a return
+buffer to acpi_evaluate_object().
+
+Fixes: d30daa33ec1d ("vfio: platform: call _RST method when using ACPI")
+Signed-off-by: Rafael Mendonca <rafaelmendsr@gmail.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Link: https://lore.kernel.org/r/20221018152825.891032-1-rafaelmendsr@gmail.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/platform/vfio_platform_common.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c
+index e83a7cd15c95..e15ef1a949e0 100644
+--- a/drivers/vfio/platform/vfio_platform_common.c
++++ b/drivers/vfio/platform/vfio_platform_common.c
+@@ -72,12 +72,11 @@ static int vfio_platform_acpi_call_reset(struct vfio_platform_device *vdev,
+                                 const char **extra_dbg)
+ {
+ #ifdef CONFIG_ACPI
+-      struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       struct device *dev = vdev->device;
+       acpi_handle handle = ACPI_HANDLE(dev);
+       acpi_status acpi_ret;
+-      acpi_ret = acpi_evaluate_object(handle, "_RST", NULL, &buffer);
++      acpi_ret = acpi_evaluate_object(handle, "_RST", NULL, NULL);
+       if (ACPI_FAILURE(acpi_ret)) {
+               if (extra_dbg)
+                       *extra_dbg = acpi_format_exception(acpi_ret);
+-- 
+2.35.1
+
diff --git a/queue-5.10/video-hyperv_fb-avoid-taking-busy-spinlock-on-panic-.patch b/queue-5.10/video-hyperv_fb-avoid-taking-busy-spinlock-on-panic-.patch
new file mode 100644 (file)
index 0000000..d7311c0
--- /dev/null
@@ -0,0 +1,106 @@
+From 544d0670e6faf086c7a0c8e2ee714761b8191217 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Aug 2022 19:17:29 -0300
+Subject: video: hyperv_fb: Avoid taking busy spinlock on panic path
+
+From: Guilherme G. Piccoli <gpiccoli@igalia.com>
+
+[ Upstream commit 1d044ca035dc22df0d3b39e56f2881071d9118bd ]
+
+The Hyper-V framebuffer code registers a panic notifier in order
+to try updating its fbdev if the kernel crashed. The notifier
+callback is straightforward, but it calls the vmbus_sendpacket()
+routine eventually, and such function takes a spinlock for the
+ring buffer operations.
+
+Panic path runs in atomic context, with local interrupts and
+preemption disabled, and all secondary CPUs shutdown. That said,
+taking a spinlock might cause a lockup if a secondary CPU was
+disabled with such lock taken. Fix it here by checking if the
+ring buffer spinlock is busy on Hyper-V framebuffer panic notifier;
+if so, bail-out avoiding the potential lockup scenario.
+
+Cc: Andrea Parri (Microsoft) <parri.andrea@gmail.com>
+Cc: Dexuan Cui <decui@microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: "K. Y. Srinivasan" <kys@microsoft.com>
+Cc: Michael Kelley <mikelley@microsoft.com>
+Cc: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Tianyu Lan <Tianyu.Lan@microsoft.com>
+Cc: Wei Liu <wei.liu@kernel.org>
+Tested-by: Fabio A M Martins <fabiomirmar@gmail.com>
+Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/20220819221731.480795-10-gpiccoli@igalia.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/ring_buffer.c        | 13 +++++++++++++
+ drivers/video/fbdev/hyperv_fb.c |  8 +++++++-
+ include/linux/hyperv.h          |  2 ++
+ 3 files changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
+index 769851b6e74c..7ed6fad3fa8f 100644
+--- a/drivers/hv/ring_buffer.c
++++ b/drivers/hv/ring_buffer.c
+@@ -246,6 +246,19 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
+       mutex_unlock(&ring_info->ring_buffer_mutex);
+ }
++/*
++ * Check if the ring buffer spinlock is available to take or not; used on
++ * atomic contexts, like panic path (see the Hyper-V framebuffer driver).
++ */
++
++bool hv_ringbuffer_spinlock_busy(struct vmbus_channel *channel)
++{
++      struct hv_ring_buffer_info *rinfo = &channel->outbound;
++
++      return spin_is_locked(&rinfo->ring_lock);
++}
++EXPORT_SYMBOL_GPL(hv_ringbuffer_spinlock_busy);
++
+ /* Write to the ring buffer. */
+ int hv_ringbuffer_write(struct vmbus_channel *channel,
+                       const struct kvec *kv_list, u32 kv_count)
+diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
+index 40baa79f8046..f0a66a344d87 100644
+--- a/drivers/video/fbdev/hyperv_fb.c
++++ b/drivers/video/fbdev/hyperv_fb.c
+@@ -798,12 +798,18 @@ static void hvfb_ondemand_refresh_throttle(struct hvfb_par *par,
+ static int hvfb_on_panic(struct notifier_block *nb,
+                        unsigned long e, void *p)
+ {
++      struct hv_device *hdev;
+       struct hvfb_par *par;
+       struct fb_info *info;
+       par = container_of(nb, struct hvfb_par, hvfb_panic_nb);
+-      par->synchronous_fb = true;
+       info = par->info;
++      hdev = device_to_hv_device(info->device);
++
++      if (hv_ringbuffer_spinlock_busy(hdev->channel))
++              return NOTIFY_DONE;
++
++      par->synchronous_fb = true;
+       if (par->need_docopy)
+               hvfb_docopy(par, 0, dio_fb_size);
+       synthvid_update(info, 0, 0, INT_MAX, INT_MAX);
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index 1ce131f29f3b..eada4d8d6587 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1269,6 +1269,8 @@ struct hv_ring_buffer_debug_info {
+ int hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
+                               struct hv_ring_buffer_debug_info *debug_info);
++bool hv_ringbuffer_spinlock_busy(struct vmbus_channel *channel);
++
+ /* Vmbus interface */
+ #define vmbus_driver_register(driver) \
+       __vmbus_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+-- 
+2.35.1
+
diff --git a/queue-5.10/vme-fix-error-not-catched-in-fake_init.patch b/queue-5.10/vme-fix-error-not-catched-in-fake_init.patch
new file mode 100644 (file)
index 0000000..67b7cc8
--- /dev/null
@@ -0,0 +1,49 @@
+From ad9ea9c468f6454e3f2aee30036a7ef3bbd3d9bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 16:48:05 +0800
+Subject: vme: Fix error not catched in fake_init()
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit 7bef797d707f1744f71156b21d41e3b8c946631f ]
+
+In fake_init(), __root_device_register() is possible to fail but it's
+ignored, which can cause unregistering vme_root fail when exit.
+
+ general protection fault,
+ probably for non-canonical address 0xdffffc000000008c
+ KASAN: null-ptr-deref in range [0x0000000000000460-0x0000000000000467]
+ RIP: 0010:root_device_unregister+0x26/0x60
+ Call Trace:
+  <TASK>
+  __x64_sys_delete_module+0x34f/0x540
+  do_syscall_64+0x38/0x90
+  entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Return error when __root_device_register() fails.
+
+Fixes: 658bcdae9c67 ("vme: Adding Fake VME driver")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Link: https://lore.kernel.org/r/20221205084805.147436-1-chenzhongjin@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vme/bridges/vme_fake.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/vme/bridges/vme_fake.c b/drivers/vme/bridges/vme_fake.c
+index 6a1bc284f297..eae78366eb02 100644
+--- a/drivers/vme/bridges/vme_fake.c
++++ b/drivers/vme/bridges/vme_fake.c
+@@ -1073,6 +1073,8 @@ static int __init fake_init(void)
+       /* We need a fake parent device */
+       vme_root = __root_device_register("vme", THIS_MODULE);
++      if (IS_ERR(vme_root))
++              return PTR_ERR(vme_root);
+       /* If we want to support more than one bridge at some point, we need to
+        * dynamically allocate this so we get one per device.
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-ar5523-fix-use-after-free-on-ar5523_cmd-timed-o.patch b/queue-5.10/wifi-ar5523-fix-use-after-free-on-ar5523_cmd-timed-o.patch
new file mode 100644 (file)
index 0000000..a40ce43
--- /dev/null
@@ -0,0 +1,110 @@
+From 556d12ec1c1fd987aee19c7cffd12fa50699e11d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Oct 2022 03:32:23 +0900
+Subject: wifi: ar5523: Fix use-after-free on ar5523_cmd() timed out
+
+From: Shigeru Yoshida <syoshida@redhat.com>
+
+[ Upstream commit b6702a942a069c2a975478d719e98d83cdae1797 ]
+
+syzkaller reported use-after-free with the stack trace like below [1]:
+
+[   38.960489][    C3] ==================================================================
+[   38.963216][    C3] BUG: KASAN: use-after-free in ar5523_cmd_tx_cb+0x220/0x240
+[   38.964950][    C3] Read of size 8 at addr ffff888048e03450 by task swapper/3/0
+[   38.966363][    C3]
+[   38.967053][    C3] CPU: 3 PID: 0 Comm: swapper/3 Not tainted 6.0.0-09039-ga6afa4199d3d-dirty #18
+[   38.968464][    C3] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-1.fc36 04/01/2014
+[   38.969959][    C3] Call Trace:
+[   38.970841][    C3]  <IRQ>
+[   38.971663][    C3]  dump_stack_lvl+0xfc/0x174
+[   38.972620][    C3]  print_report.cold+0x2c3/0x752
+[   38.973626][    C3]  ? ar5523_cmd_tx_cb+0x220/0x240
+[   38.974644][    C3]  kasan_report+0xb1/0x1d0
+[   38.975720][    C3]  ? ar5523_cmd_tx_cb+0x220/0x240
+[   38.976831][    C3]  ar5523_cmd_tx_cb+0x220/0x240
+[   38.978412][    C3]  __usb_hcd_giveback_urb+0x353/0x5b0
+[   38.979755][    C3]  usb_hcd_giveback_urb+0x385/0x430
+[   38.981266][    C3]  dummy_timer+0x140c/0x34e0
+[   38.982925][    C3]  ? notifier_call_chain+0xb5/0x1e0
+[   38.984761][    C3]  ? rcu_read_lock_sched_held+0xb/0x60
+[   38.986242][    C3]  ? lock_release+0x51c/0x790
+[   38.987323][    C3]  ? _raw_read_unlock_irqrestore+0x37/0x70
+[   38.988483][    C3]  ? __wake_up_common_lock+0xde/0x130
+[   38.989621][    C3]  ? reacquire_held_locks+0x4a0/0x4a0
+[   38.990777][    C3]  ? lock_acquire+0x472/0x550
+[   38.991919][    C3]  ? rcu_read_lock_sched_held+0xb/0x60
+[   38.993138][    C3]  ? lock_acquire+0x472/0x550
+[   38.994890][    C3]  ? dummy_urb_enqueue+0x860/0x860
+[   38.996266][    C3]  ? do_raw_spin_unlock+0x16f/0x230
+[   38.997670][    C3]  ? dummy_urb_enqueue+0x860/0x860
+[   38.999116][    C3]  call_timer_fn+0x1a0/0x6a0
+[   39.000668][    C3]  ? add_timer_on+0x4a0/0x4a0
+[   39.002137][    C3]  ? reacquire_held_locks+0x4a0/0x4a0
+[   39.003809][    C3]  ? __next_timer_interrupt+0x226/0x2a0
+[   39.005509][    C3]  __run_timers.part.0+0x69a/0xac0
+[   39.007025][    C3]  ? dummy_urb_enqueue+0x860/0x860
+[   39.008716][    C3]  ? call_timer_fn+0x6a0/0x6a0
+[   39.010254][    C3]  ? cpuacct_percpu_seq_show+0x10/0x10
+[   39.011795][    C3]  ? kvm_sched_clock_read+0x14/0x40
+[   39.013277][    C3]  ? sched_clock_cpu+0x69/0x2b0
+[   39.014724][    C3]  run_timer_softirq+0xb6/0x1d0
+[   39.016196][    C3]  __do_softirq+0x1d2/0x9be
+[   39.017616][    C3]  __irq_exit_rcu+0xeb/0x190
+[   39.019004][    C3]  irq_exit_rcu+0x5/0x20
+[   39.020361][    C3]  sysvec_apic_timer_interrupt+0x8f/0xb0
+[   39.021965][    C3]  </IRQ>
+[   39.023237][    C3]  <TASK>
+
+In ar5523_probe(), ar5523_host_available() calls ar5523_cmd() as below
+(there are other functions which finally call ar5523_cmd()):
+
+ar5523_probe()
+-> ar5523_host_available()
+   -> ar5523_cmd_read()
+      -> ar5523_cmd()
+
+If ar5523_cmd() timed out, then ar5523_host_available() failed and
+ar5523_probe() freed the device structure.  So, ar5523_cmd_tx_cb()
+might touch the freed structure.
+
+This patch fixes this issue by canceling in-flight tx cmd if submitted
+urb timed out.
+
+Link: https://syzkaller.appspot.com/bug?id=9e12b2d54300842b71bdd18b54971385ff0d0d3a [1]
+Reported-by: syzbot+95001b1fd6dfcc716c29@syzkaller.appspotmail.com
+Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20221009183223.420015-1-syoshida@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ar5523/ar5523.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
+index 1baec4b412c8..efe38b2c1df7 100644
+--- a/drivers/net/wireless/ath/ar5523/ar5523.c
++++ b/drivers/net/wireless/ath/ar5523/ar5523.c
+@@ -241,6 +241,11 @@ static void ar5523_cmd_tx_cb(struct urb *urb)
+       }
+ }
++static void ar5523_cancel_tx_cmd(struct ar5523 *ar)
++{
++      usb_kill_urb(ar->tx_cmd.urb_tx);
++}
++
+ static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata,
+                     int ilen, void *odata, int olen, int flags)
+ {
+@@ -280,6 +285,7 @@ static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata,
+       }
+       if (!wait_for_completion_timeout(&cmd->done, 2 * HZ)) {
++              ar5523_cancel_tx_cmd(ar);
+               cmd->odata = NULL;
+               ar5523_err(ar, "timeout waiting for command %02x reply\n",
+                          code);
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-ath10k-fix-return-value-in-ath10k_pci_init.patch b/queue-5.10/wifi-ath10k-fix-return-value-in-ath10k_pci_init.patch
new file mode 100644 (file)
index 0000000..eada9c0
--- /dev/null
@@ -0,0 +1,63 @@
+From df30ebaae382d9be96a77e869a13c5f016190744 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 14:19:26 +0800
+Subject: wifi: ath10k: Fix return value in ath10k_pci_init()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 2af7749047d8d6ad43feff69f555a13a6a6c2831 ]
+
+This driver is attempting to register to support two different buses.
+if either of these is successful then ath10k_pci_init() should return 0
+so that hardware attached to the successful bus can be probed and
+supported. only if both of these are unsuccessful should ath10k_pci_init()
+return an errno.
+
+Fixes: 0b523ced9a3c ("ath10k: add basic skeleton to support ahb")
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Reviewed-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20221110061926.18163-1-xiujianfeng@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/pci.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
+index 86f52bcb3e4d..67e240327fb3 100644
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -3799,18 +3799,22 @@ static struct pci_driver ath10k_pci_driver = {
+ static int __init ath10k_pci_init(void)
+ {
+-      int ret;
++      int ret1, ret2;
+-      ret = pci_register_driver(&ath10k_pci_driver);
+-      if (ret)
++      ret1 = pci_register_driver(&ath10k_pci_driver);
++      if (ret1)
+               printk(KERN_ERR "failed to register ath10k pci driver: %d\n",
+-                     ret);
++                     ret1);
+-      ret = ath10k_ahb_init();
+-      if (ret)
+-              printk(KERN_ERR "ahb init failed: %d\n", ret);
++      ret2 = ath10k_ahb_init();
++      if (ret2)
++              printk(KERN_ERR "ahb init failed: %d\n", ret2);
+-      return ret;
++      if (ret1 && ret2)
++              return ret1;
++
++      /* registered to at least one bus */
++      return 0;
+ }
+ module_init(ath10k_pci_init);
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-ath9k-hif_usb-fix-memory-leak-of-urbs-in-ath9k_.patch b/queue-5.10/wifi-ath9k-hif_usb-fix-memory-leak-of-urbs-in-ath9k_.patch
new file mode 100644 (file)
index 0000000..1184919
--- /dev/null
@@ -0,0 +1,61 @@
+From 208a906183447bc594bcd94b218476e6f9efcab5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 18:13:59 +0300
+Subject: wifi: ath9k: hif_usb: fix memory leak of urbs in
+ ath9k_hif_usb_dealloc_tx_urbs()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit c2a94de38c74e86f49124ac14f093d6a5c377a90 ]
+
+Syzkaller reports a long-known leak of urbs in
+ath9k_hif_usb_dealloc_tx_urbs().
+
+The cause of the leak is that usb_get_urb() is called but usb_free_urb()
+(or usb_put_urb()) is not called inside usb_kill_urb() as urb->dev or
+urb->ep fields have not been initialized and usb_kill_urb() returns
+immediately.
+
+The patch removes trying to kill urbs located in hif_dev->tx.tx_buf
+because hif_dev->tx.tx_buf is not supposed to contain urbs which are in
+pending state (the pending urbs are stored in hif_dev->tx.tx_pending).
+The tx.tx_lock is acquired so there should not be any changes in the list.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: 03fb92a432ea ("ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs()")
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220725151359.283704-1-pchelkin@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/hif_usb.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
+index f06eec99de68..e66518d86882 100644
+--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
+@@ -781,14 +781,10 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
+       spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
+       list_for_each_entry_safe(tx_buf, tx_buf_tmp,
+                                &hif_dev->tx.tx_buf, list) {
+-              usb_get_urb(tx_buf->urb);
+-              spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
+-              usb_kill_urb(tx_buf->urb);
+               list_del(&tx_buf->list);
+               usb_free_urb(tx_buf->urb);
+               kfree(tx_buf->buf);
+               kfree(tx_buf);
+-              spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
+       }
+       spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-ath9k-hif_usb-fix-use-after-free-in-ath9k_hif_u.patch b/queue-5.10/wifi-ath9k-hif_usb-fix-use-after-free-in-ath9k_hif_u.patch
new file mode 100644 (file)
index 0000000..263a5dd
--- /dev/null
@@ -0,0 +1,118 @@
+From 7767ddd5a8b850ccd05b1d19053acef583e713e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Oct 2022 14:49:17 +0300
+Subject: wifi: ath9k: hif_usb: Fix use-after-free in ath9k_hif_usb_reg_in_cb()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit dd95f2239fc846795fc926787c3ae0ca701c9840 ]
+
+It is possible that skb is freed in ath9k_htc_rx_msg(), then
+usb_submit_urb() fails and we try to free skb again. It causes
+use-after-free bug. Moreover, if alloc_skb() fails, urb->context becomes
+NULL but rx_buf is not freed and there can be a memory leak.
+
+The patch removes unnecessary nskb and makes skb processing more clear: it
+is supposed that ath9k_htc_rx_msg() either frees old skb or passes its
+managing to another callback function.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: 3deff76095c4 ("ath9k_htc: Increase URB count for REG_IN pipe")
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20221008114917.21404-1-pchelkin@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/hif_usb.c | 28 +++++++++++++-----------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
+index e66518d86882..e5d5b0761881 100644
+--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
+@@ -709,14 +709,13 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
+       struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
+       struct hif_device_usb *hif_dev = rx_buf->hif_dev;
+       struct sk_buff *skb = rx_buf->skb;
+-      struct sk_buff *nskb;
+       int ret;
+       if (!skb)
+               return;
+       if (!hif_dev)
+-              goto free;
++              goto free_skb;
+       switch (urb->status) {
+       case 0:
+@@ -725,7 +724,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
+       case -ECONNRESET:
+       case -ENODEV:
+       case -ESHUTDOWN:
+-              goto free;
++              goto free_skb;
+       default:
+               skb_reset_tail_pointer(skb);
+               skb_trim(skb, 0);
+@@ -736,25 +735,27 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
+       if (likely(urb->actual_length != 0)) {
+               skb_put(skb, urb->actual_length);
+-              /* Process the command first */
++              /*
++               * Process the command first.
++               * skb is either freed here or passed to be
++               * managed to another callback function.
++               */
+               ath9k_htc_rx_msg(hif_dev->htc_handle, skb,
+                                skb->len, USB_REG_IN_PIPE);
+-
+-              nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
+-              if (!nskb) {
++              skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
++              if (!skb) {
+                       dev_err(&hif_dev->udev->dev,
+                               "ath9k_htc: REG_IN memory allocation failure\n");
+-                      urb->context = NULL;
+-                      return;
++                      goto free_rx_buf;
+               }
+-              rx_buf->skb = nskb;
++              rx_buf->skb = skb;
+               usb_fill_int_urb(urb, hif_dev->udev,
+                                usb_rcvintpipe(hif_dev->udev,
+                                                USB_REG_IN_PIPE),
+-                               nskb->data, MAX_REG_IN_BUF_SIZE,
++                               skb->data, MAX_REG_IN_BUF_SIZE,
+                                ath9k_hif_usb_reg_in_cb, rx_buf, 1);
+       }
+@@ -763,12 +764,13 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
+       ret = usb_submit_urb(urb, GFP_ATOMIC);
+       if (ret) {
+               usb_unanchor_urb(urb);
+-              goto free;
++              goto free_skb;
+       }
+       return;
+-free:
++free_skb:
+       kfree_skb(skb);
++free_rx_buf:
+       kfree(rx_buf);
+       urb->context = NULL;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-ath9k-verify-the-expected-usb_endpoints-are-pre.patch b/queue-5.10/wifi-ath9k-verify-the-expected-usb_endpoints-are-pre.patch
new file mode 100644 (file)
index 0000000..eecc41d
--- /dev/null
@@ -0,0 +1,80 @@
+From 28b9bdba0bd5e4dcb3e915deb8fa66ed87c227da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Oct 2022 00:15:32 +0300
+Subject: wifi: ath9k: verify the expected usb_endpoints are present
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit 16ef02bad239f11f322df8425d302be62f0443ce ]
+
+The bug arises when a USB device claims to be an ATH9K but doesn't
+have the expected endpoints. (In this case there was an interrupt
+endpoint where the driver expected a bulk endpoint.) The kernel
+needs to be able to handle such devices without getting an internal error.
+
+usb 1-1: BOGUS urb xfer, pipe 3 != type 1
+WARNING: CPU: 3 PID: 500 at drivers/usb/core/urb.c:493 usb_submit_urb+0xce2/0x1430 drivers/usb/core/urb.c:493
+Modules linked in:
+CPU: 3 PID: 500 Comm: kworker/3:2 Not tainted 5.10.135-syzkaller #0
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
+Workqueue: events request_firmware_work_func
+RIP: 0010:usb_submit_urb+0xce2/0x1430 drivers/usb/core/urb.c:493
+Call Trace:
+ ath9k_hif_usb_alloc_rx_urbs drivers/net/wireless/ath/ath9k/hif_usb.c:908 [inline]
+ ath9k_hif_usb_alloc_urbs+0x75e/0x1010 drivers/net/wireless/ath/ath9k/hif_usb.c:1019
+ ath9k_hif_usb_dev_init drivers/net/wireless/ath/ath9k/hif_usb.c:1109 [inline]
+ ath9k_hif_usb_firmware_cb+0x142/0x530 drivers/net/wireless/ath/ath9k/hif_usb.c:1242
+ request_firmware_work_func+0x12e/0x240 drivers/base/firmware_loader/main.c:1097
+ process_one_work+0x9af/0x1600 kernel/workqueue.c:2279
+ worker_thread+0x61d/0x12f0 kernel/workqueue.c:2425
+ kthread+0x3b4/0x4a0 kernel/kthread.c:313
+ ret_from_fork+0x22/0x30 arch/x86/entry/entry_64.S:299
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20221008211532.74583-1-pchelkin@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/hif_usb.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
+index e5d5b0761881..f938ac1a4abd 100644
+--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
+@@ -1328,10 +1328,24 @@ static int send_eject_command(struct usb_interface *interface)
+ static int ath9k_hif_usb_probe(struct usb_interface *interface,
+                              const struct usb_device_id *id)
+ {
++      struct usb_endpoint_descriptor *bulk_in, *bulk_out, *int_in, *int_out;
+       struct usb_device *udev = interface_to_usbdev(interface);
++      struct usb_host_interface *alt;
+       struct hif_device_usb *hif_dev;
+       int ret = 0;
++      /* Verify the expected endpoints are present */
++      alt = interface->cur_altsetting;
++      if (usb_find_common_endpoints(alt, &bulk_in, &bulk_out, &int_in, &int_out) < 0 ||
++          usb_endpoint_num(bulk_in) != USB_WLAN_RX_PIPE ||
++          usb_endpoint_num(bulk_out) != USB_WLAN_TX_PIPE ||
++          usb_endpoint_num(int_in) != USB_REG_IN_PIPE ||
++          usb_endpoint_num(int_out) != USB_REG_OUT_PIPE) {
++              dev_err(&udev->dev,
++                      "ath9k_htc: Device endpoint numbers are not the expected ones\n");
++              return -ENODEV;
++      }
++
+       if (id->driver_info == STORAGE_DEVICE)
+               return send_eject_command(interface);
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-brcmfmac-fix-error-return-code-in-brcmf_sdio_do.patch b/queue-5.10/wifi-brcmfmac-fix-error-return-code-in-brcmf_sdio_do.patch
new file mode 100644 (file)
index 0000000..6e50557
--- /dev/null
@@ -0,0 +1,53 @@
+From 16692c30dd2492481156251db2c5049f4eb41df8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 13:35:42 +0800
+Subject: wifi: brcmfmac: Fix error return code in
+ brcmf_sdio_download_firmware()
+
+From: Wang Yufen <wangyufen@huawei.com>
+
+[ Upstream commit c2f2924bc7f9ea75ef8d95863e710168f8196256 ]
+
+Fix to return a negative error code instead of 0 when
+brcmf_chip_set_active() fails. In addition, change the return
+value for brcmf_pcie_exit_download_state() to keep consistent.
+
+Fixes: d380ebc9b6fb ("brcmfmac: rename chip download functions")
+Signed-off-by: Wang Yufen <wangyufen@huawei.com>
+Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/1669959342-27144-1-git-send-email-wangyufen@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+index 61febc9bfa14..4e9d2b3659f0 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -618,7 +618,7 @@ static int brcmf_pcie_exit_download_state(struct brcmf_pciedev_info *devinfo,
+       }
+       if (!brcmf_chip_set_active(devinfo->ci, resetintr))
+-              return -EINVAL;
++              return -EIO;
+       return 0;
+ }
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index 9929e90866f0..3c0d5c68eaca 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -3401,6 +3401,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
+       /* Take arm out of reset */
+       if (!brcmf_chip_set_active(bus->ci, rstvec)) {
+               brcmf_err("error getting out of ARM core reset\n");
++              bcmerror = -EIO;
+               goto err;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-brcmfmac-fix-potential-shift-out-of-bounds-in-b.patch b/queue-5.10/wifi-brcmfmac-fix-potential-shift-out-of-bounds-in-b.patch
new file mode 100644 (file)
index 0000000..9efbdc7
--- /dev/null
@@ -0,0 +1,149 @@
+From 0f52d9585c2bc8fb2917c18121c1aade0a60cd16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Oct 2022 16:13:29 +0900
+Subject: wifi: brcmfmac: Fix potential shift-out-of-bounds in
+ brcmf_fw_alloc_request()
+
+From: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+
+[ Upstream commit 81d17f6f3331f03c8eafdacea68ab773426c1e3c ]
+
+This patch fixes a shift-out-of-bounds in brcmfmac that occurs in
+BIT(chiprev) when a 'chiprev' provided by the device is too large.
+It should also not be equal to or greater than BITS_PER_TYPE(u32)
+as we do bitwise AND with a u32 variable and BIT(chiprev). The patch
+adds a check that makes the function return NULL if that is the case.
+Note that the NULL case is later handled by the bus-specific caller,
+brcmf_usb_probe_cb() or brcmf_usb_reset_resume(), for example.
+
+Found by a modified version of syzkaller.
+
+UBSAN: shift-out-of-bounds in drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+shift exponent 151055786 is too large for 64-bit type 'long unsigned int'
+CPU: 0 PID: 1885 Comm: kworker/0:2 Tainted: G           O      5.14.0+ #132
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
+Workqueue: usb_hub_wq hub_event
+Call Trace:
+ dump_stack_lvl+0x57/0x7d
+ ubsan_epilogue+0x5/0x40
+ __ubsan_handle_shift_out_of_bounds.cold+0x53/0xdb
+ ? lock_chain_count+0x20/0x20
+ brcmf_fw_alloc_request.cold+0x19/0x3ea
+ ? brcmf_fw_get_firmwares+0x250/0x250
+ ? brcmf_usb_ioctl_resp_wait+0x1a7/0x1f0
+ brcmf_usb_get_fwname+0x114/0x1a0
+ ? brcmf_usb_reset_resume+0x120/0x120
+ ? number+0x6c4/0x9a0
+ brcmf_c_process_clm_blob+0x168/0x590
+ ? put_dec+0x90/0x90
+ ? enable_ptr_key_workfn+0x20/0x20
+ ? brcmf_common_pd_remove+0x50/0x50
+ ? rcu_read_lock_sched_held+0xa1/0xd0
+ brcmf_c_preinit_dcmds+0x673/0xc40
+ ? brcmf_c_set_joinpref_default+0x100/0x100
+ ? rcu_read_lock_sched_held+0xa1/0xd0
+ ? rcu_read_lock_bh_held+0xb0/0xb0
+ ? lock_acquire+0x19d/0x4e0
+ ? find_held_lock+0x2d/0x110
+ ? brcmf_usb_deq+0x1cc/0x260
+ ? mark_held_locks+0x9f/0xe0
+ ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+ ? _raw_spin_unlock_irqrestore+0x47/0x50
+ ? trace_hardirqs_on+0x1c/0x120
+ ? brcmf_usb_deq+0x1a7/0x260
+ ? brcmf_usb_rx_fill_all+0x5a/0xf0
+ brcmf_attach+0x246/0xd40
+ ? wiphy_new_nm+0x1476/0x1d50
+ ? kmemdup+0x30/0x40
+ brcmf_usb_probe+0x12de/0x1690
+ ? brcmf_usbdev_qinit.constprop.0+0x470/0x470
+ usb_probe_interface+0x25f/0x710
+ really_probe+0x1be/0xa90
+ __driver_probe_device+0x2ab/0x460
+ ? usb_match_id.part.0+0x88/0xc0
+ driver_probe_device+0x49/0x120
+ __device_attach_driver+0x18a/0x250
+ ? driver_allows_async_probing+0x120/0x120
+ bus_for_each_drv+0x123/0x1a0
+ ? bus_rescan_devices+0x20/0x20
+ ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+ ? trace_hardirqs_on+0x1c/0x120
+ __device_attach+0x207/0x330
+ ? device_bind_driver+0xb0/0xb0
+ ? kobject_uevent_env+0x230/0x12c0
+ bus_probe_device+0x1a2/0x260
+ device_add+0xa61/0x1ce0
+ ? __mutex_unlock_slowpath+0xe7/0x660
+ ? __fw_devlink_link_to_suppliers+0x550/0x550
+ usb_set_configuration+0x984/0x1770
+ ? kernfs_create_link+0x175/0x230
+ usb_generic_driver_probe+0x69/0x90
+ usb_probe_device+0x9c/0x220
+ really_probe+0x1be/0xa90
+ __driver_probe_device+0x2ab/0x460
+ driver_probe_device+0x49/0x120
+ __device_attach_driver+0x18a/0x250
+ ? driver_allows_async_probing+0x120/0x120
+ bus_for_each_drv+0x123/0x1a0
+ ? bus_rescan_devices+0x20/0x20
+ ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+ ? trace_hardirqs_on+0x1c/0x120
+ __device_attach+0x207/0x330
+ ? device_bind_driver+0xb0/0xb0
+ ? kobject_uevent_env+0x230/0x12c0
+ bus_probe_device+0x1a2/0x260
+ device_add+0xa61/0x1ce0
+ ? __fw_devlink_link_to_suppliers+0x550/0x550
+ usb_new_device.cold+0x463/0xf66
+ ? hub_disconnect+0x400/0x400
+ ? _raw_spin_unlock_irq+0x24/0x30
+ hub_event+0x10d5/0x3330
+ ? hub_port_debounce+0x280/0x280
+ ? __lock_acquire+0x1671/0x5790
+ ? wq_calc_node_cpumask+0x170/0x2a0
+ ? lock_release+0x640/0x640
+ ? rcu_read_lock_sched_held+0xa1/0xd0
+ ? rcu_read_lock_bh_held+0xb0/0xb0
+ ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+ process_one_work+0x873/0x13e0
+ ? lock_release+0x640/0x640
+ ? pwq_dec_nr_in_flight+0x320/0x320
+ ? rwlock_bug.part.0+0x90/0x90
+ worker_thread+0x8b/0xd10
+ ? __kthread_parkme+0xd9/0x1d0
+ ? process_one_work+0x13e0/0x13e0
+ kthread+0x379/0x450
+ ? _raw_spin_unlock_irq+0x24/0x30
+ ? set_kthread_struct+0x100/0x100
+ ret_from_fork+0x1f/0x30
+
+Reported-by: Dokyung Song <dokyungs@yonsei.ac.kr>
+Reported-by: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+Reported-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+Signed-off-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221024071329.504277-1-linuxlovemin@yonsei.ac.kr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+index a2b8d9171af2..060889bf6d05 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+@@ -703,6 +703,11 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev,
+       u32 i, j;
+       char end = '\0';
++      if (chiprev >= BITS_PER_TYPE(u32)) {
++              brcmf_err("Invalid chip revision %u\n", chiprev);
++              return NULL;
++      }
++
+       for (i = 0; i < table_size; i++) {
+               if (mapping_table[i].chipid == chip &&
+                   mapping_table[i].revmask & BIT(chiprev))
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-cfg80211-fix-not-unregister-reg_pdev-when-load_.patch b/queue-5.10/wifi-cfg80211-fix-not-unregister-reg_pdev-when-load_.patch
new file mode 100644 (file)
index 0000000..8efa269
--- /dev/null
@@ -0,0 +1,57 @@
+From 8fc915af2694212cb5ddbd4de70ec9f486b56440 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 17:02:37 +0800
+Subject: wifi: cfg80211: Fix not unregister reg_pdev when
+ load_builtin_regdb_keys() fails
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit 833a9fd28c9b7ccb39a334721379e992dc1c0c89 ]
+
+In regulatory_init_db(), when it's going to return a error, reg_pdev
+should be unregistered. When load_builtin_regdb_keys() fails it doesn't
+do it and makes cfg80211 can't be reload with report:
+
+sysfs: cannot create duplicate filename '/devices/platform/regulatory.0'
+ ...
+ <TASK>
+ dump_stack_lvl+0x79/0x9b
+ sysfs_warn_dup.cold+0x1c/0x29
+ sysfs_create_dir_ns+0x22d/0x290
+ kobject_add_internal+0x247/0x800
+ kobject_add+0x135/0x1b0
+ device_add+0x389/0x1be0
+ platform_device_add+0x28f/0x790
+ platform_device_register_full+0x376/0x4b0
+ regulatory_init+0x9a/0x4b2 [cfg80211]
+ cfg80211_init+0x84/0x113 [cfg80211]
+ ...
+
+Fixes: 90a53e4432b1 ("cfg80211: implement regdb signature checking")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Link: https://lore.kernel.org/r/20221109090237.214127-1-chenzhongjin@huawei.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/reg.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index a1e64d967bd3..90297264d8ae 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -4185,8 +4185,10 @@ static int __init regulatory_init_db(void)
+               return -EINVAL;
+       err = load_builtin_regdb_keys();
+-      if (err)
++      if (err) {
++              platform_device_unregister(reg_pdev);
+               return err;
++      }
+       /* We always try to get an update for the static regdomain */
+       err = regulatory_hint_core(cfg80211_world_regdom->alpha2);
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-iwlwifi-mvm-fix-double-free-on-tx-path.patch b/queue-5.10/wifi-iwlwifi-mvm-fix-double-free-on-tx-path.patch
new file mode 100644 (file)
index 0000000..af767ed
--- /dev/null
@@ -0,0 +1,215 @@
+From cc5bd252eb1e284ef9c7202f24aafb9856efb859 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 23:02:06 +0200
+Subject: wifi: iwlwifi: mvm: fix double free on tx path.
+
+From: Ben Greear <greearb@candelatech.com>
+
+[ Upstream commit 0473cbae2137b963bd0eaa74336131cb1d3bc6c3 ]
+
+We see kernel crashes and lockups and KASAN errors related to ax210
+firmware crashes.  One of the KASAN dumps pointed at the tx path,
+and it appears there is indeed a way to double-free an skb.
+
+If iwl_mvm_tx_skb_sta returns non-zero, then the 'skb' sent into the
+method will be freed.  But, in case where we build TSO skb buffer,
+the skb may also be freed in error case.  So, return 0 in that particular
+error case and do cleanup manually.
+
+BUG: KASAN: use-after-free in __list_del_entry_valid+0x12/0x90
+iwlwifi 0000:06:00.0: 0x00000000 | tsf hi
+Read of size 8 at addr ffff88813cfa4ba0 by task btserver/9650
+
+CPU: 4 PID: 9650 Comm: btserver Tainted: G        W         5.19.8+ #5
+iwlwifi 0000:06:00.0: 0x00000000 | time gp1
+Hardware name: Default string Default string/SKYBAY, BIOS 5.12 02/19/2019
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x55/0x6d
+ print_report.cold.12+0xf2/0x684
+iwlwifi 0000:06:00.0: 0x1D0915A8 | time gp2
+ ? __list_del_entry_valid+0x12/0x90
+ kasan_report+0x8b/0x180
+iwlwifi 0000:06:00.0: 0x00000001 | uCode revision type
+ ? __list_del_entry_valid+0x12/0x90
+ __list_del_entry_valid+0x12/0x90
+iwlwifi 0000:06:00.0: 0x00000048 | uCode version major
+ tcp_update_skb_after_send+0x5d/0x170
+ __tcp_transmit_skb+0xb61/0x15c0
+iwlwifi 0000:06:00.0: 0xDAA05125 | uCode version minor
+ ? __tcp_select_window+0x490/0x490
+iwlwifi 0000:06:00.0: 0x00000420 | hw version
+ ? trace_kmalloc_node+0x29/0xd0
+ ? __kmalloc_node_track_caller+0x12a/0x260
+ ? memset+0x1f/0x40
+ ? __build_skb_around+0x125/0x150
+ ? __alloc_skb+0x1d4/0x220
+ ? skb_zerocopy_clone+0x55/0x230
+iwlwifi 0000:06:00.0: 0x00489002 | board version
+ ? kmalloc_reserve+0x80/0x80
+ ? rcu_read_lock_bh_held+0x60/0xb0
+ tcp_write_xmit+0x3f1/0x24d0
+iwlwifi 0000:06:00.0: 0x034E001C | hcmd
+ ? __check_object_size+0x180/0x350
+iwlwifi 0000:06:00.0: 0x24020000 | isr0
+ tcp_sendmsg_locked+0x8a9/0x1520
+iwlwifi 0000:06:00.0: 0x01400000 | isr1
+ ? tcp_sendpage+0x50/0x50
+iwlwifi 0000:06:00.0: 0x48F0000A | isr2
+ ? lock_release+0xb9/0x400
+ ? tcp_sendmsg+0x14/0x40
+iwlwifi 0000:06:00.0: 0x00C3080C | isr3
+ ? lock_downgrade+0x390/0x390
+ ? do_raw_spin_lock+0x114/0x1d0
+iwlwifi 0000:06:00.0: 0x00200000 | isr4
+ ? rwlock_bug.part.2+0x50/0x50
+iwlwifi 0000:06:00.0: 0x034A001C | last cmd Id
+ ? rwlock_bug.part.2+0x50/0x50
+ ? lockdep_hardirqs_on_prepare+0xe/0x200
+iwlwifi 0000:06:00.0: 0x0000C2F0 | wait_event
+ ? __local_bh_enable_ip+0x87/0xe0
+ ? inet_send_prepare+0x220/0x220
+iwlwifi 0000:06:00.0: 0x000000C4 | l2p_control
+ tcp_sendmsg+0x22/0x40
+ sock_sendmsg+0x5f/0x70
+iwlwifi 0000:06:00.0: 0x00010034 | l2p_duration
+ __sys_sendto+0x19d/0x250
+iwlwifi 0000:06:00.0: 0x00000007 | l2p_mhvalid
+ ? __ia32_sys_getpeername+0x40/0x40
+iwlwifi 0000:06:00.0: 0x00000000 | l2p_addr_match
+ ? rcu_read_lock_held_common+0x12/0x50
+ ? rcu_read_lock_sched_held+0x5a/0xd0
+ ? rcu_read_lock_bh_held+0xb0/0xb0
+ ? rcu_read_lock_sched_held+0x5a/0xd0
+ ? rcu_read_lock_sched_held+0x5a/0xd0
+ ? lock_release+0xb9/0x400
+ ? lock_downgrade+0x390/0x390
+ ? ktime_get+0x64/0x130
+ ? ktime_get+0x8d/0x130
+ ? rcu_read_lock_held_common+0x12/0x50
+ ? rcu_read_lock_sched_held+0x5a/0xd0
+ ? rcu_read_lock_held_common+0x12/0x50
+ ? rcu_read_lock_sched_held+0x5a/0xd0
+ ? rcu_read_lock_bh_held+0xb0/0xb0
+ ? rcu_read_lock_bh_held+0xb0/0xb0
+ __x64_sys_sendto+0x6f/0x80
+ do_syscall_64+0x34/0xb0
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+RIP: 0033:0x7f1d126e4531
+Code: 00 00 00 00 0f 1f 44 00 00 f3 0f 1e fa 48 8d 05 35 80 0c 00 41 89 ca 8b 00 85 c0 75 1c 45 31 c9 45 31 c0 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 67 c3 66 0f 1f 44 00 00 55 48 83 ec 20 48 89
+RSP: 002b:00007ffe21a679d8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
+RAX: ffffffffffffffda RBX: 000000000000ffdc RCX: 00007f1d126e4531
+RDX: 0000000000010000 RSI: 000000000374acf0 RDI: 0000000000000014
+RBP: 00007ffe21a67ac0 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000010
+R13: 0000000000000000 R14: 0000000000000001 R15: 0000000000000000
+ </TASK>
+
+Allocated by task 9650:
+ kasan_save_stack+0x1c/0x40
+ __kasan_slab_alloc+0x6d/0x90
+ kmem_cache_alloc_node+0xf3/0x2b0
+ __alloc_skb+0x191/0x220
+ tcp_stream_alloc_skb+0x3f/0x330
+ tcp_sendmsg_locked+0x67c/0x1520
+ tcp_sendmsg+0x22/0x40
+ sock_sendmsg+0x5f/0x70
+ __sys_sendto+0x19d/0x250
+ __x64_sys_sendto+0x6f/0x80
+ do_syscall_64+0x34/0xb0
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+Freed by task 9650:
+ kasan_save_stack+0x1c/0x40
+ kasan_set_track+0x21/0x30
+ kasan_set_free_info+0x20/0x30
+ __kasan_slab_free+0x102/0x170
+ kmem_cache_free+0xc8/0x3e0
+ iwl_mvm_mac_itxq_xmit+0x124/0x270 [iwlmvm]
+ ieee80211_queue_skb+0x874/0xd10 [mac80211]
+ ieee80211_xmit_fast+0xf80/0x1180 [mac80211]
+ __ieee80211_subif_start_xmit+0x287/0x680 [mac80211]
+ ieee80211_subif_start_xmit+0xcd/0x730 [mac80211]
+ dev_hard_start_xmit+0xf6/0x420
+ __dev_queue_xmit+0x165b/0x1b50
+ ip_finish_output2+0x66e/0xfb0
+ __ip_finish_output+0x487/0x6d0
+ ip_output+0x11c/0x350
+ __ip_queue_xmit+0x36b/0x9d0
+ __tcp_transmit_skb+0xb35/0x15c0
+ tcp_write_xmit+0x3f1/0x24d0
+ tcp_sendmsg_locked+0x8a9/0x1520
+ tcp_sendmsg+0x22/0x40
+ sock_sendmsg+0x5f/0x70
+ __sys_sendto+0x19d/0x250
+ __x64_sys_sendto+0x6f/0x80
+ do_syscall_64+0x34/0xb0
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+The buggy address belongs to the object at ffff88813cfa4b40
+ which belongs to the cache skbuff_fclone_cache of size 472
+The buggy address is located 96 bytes inside of
+ 472-byte region [ffff88813cfa4b40, ffff88813cfa4d18)
+
+The buggy address belongs to the physical page:
+page:ffffea0004f3e900 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff88813cfa6c40 pfn:0x13cfa4
+head:ffffea0004f3e900 order:2 compound_mapcount:0 compound_pincount:0
+flags: 0x5fff8000010200(slab|head|node=0|zone=2|lastcpupid=0x3fff)
+raw: 005fff8000010200 ffffea0004656b08 ffffea0008e8cf08 ffff8881081a5240
+raw: ffff88813cfa6c40 0000000000170015 00000001ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffff88813cfa4a80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ffff88813cfa4b00: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
+>ffff88813cfa4b80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+                               ^
+ ffff88813cfa4c00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff88813cfa4c80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+==================================================================
+
+Fixes: 08f7d8b69aaf ("iwlwifi: mvm: bring back mvm GSO code")
+Link: https://lore.kernel.org/linux-wireless/20220928193057.16132-1-greearb@candelatech.com/
+Tested-by: Amol Jawale <amol.jawale@candelatech.com>
+Signed-off-by: Ben Greear <greearb@candelatech.com>
+Link: https://lore.kernel.org/r/20221123225313.21b1ee31d666.I3b3ba184433dd2a544d91eeeda29b467021824ae@changeid
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+index 7186e1dbbd6b..d310337b1625 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+@@ -1203,6 +1203,7 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
+       struct sk_buff_head mpdus_skbs;
+       unsigned int payload_len;
+       int ret;
++      struct sk_buff *orig_skb = skb;
+       if (WARN_ON_ONCE(!mvmsta))
+               return -1;
+@@ -1235,8 +1236,17 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
+               ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
+               if (ret) {
++                      /* Free skbs created as part of TSO logic that have not yet been dequeued */
+                       __skb_queue_purge(&mpdus_skbs);
+-                      return ret;
++                      /* skb here is not necessarily same as skb that entered this method,
++                       * so free it explicitly.
++                       */
++                      if (skb == orig_skb)
++                              ieee80211_free_txskb(mvm->hw, skb);
++                      else
++                              kfree_skb(skb);
++                      /* there was error, but we consumed skb one way or another, so return 0 */
++                      return 0;
+               }
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-mac80211-fix-memory-leak-in-ieee80211_if_add.patch b/queue-5.10/wifi-mac80211-fix-memory-leak-in-ieee80211_if_add.patch
new file mode 100644 (file)
index 0000000..56aa4df
--- /dev/null
@@ -0,0 +1,36 @@
+From 3b6fba8e61d4c1a1c38a563049c2eeeec66cb7dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 14:45:00 +0800
+Subject: wifi: mac80211: fix memory leak in ieee80211_if_add()
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 13e5afd3d773c6fc6ca2b89027befaaaa1ea7293 ]
+
+When register_netdevice() failed in ieee80211_if_add(), ndev->tstats
+isn't released. Fix it.
+
+Fixes: 5a490510ba5f ("mac80211: use per-CPU TX/RX statistics")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Link: https://lore.kernel.org/r/20221117064500.319983-1-shaozhengchao@huawei.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/iface.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 3a15ef8dd322..d04e5a1a7e0e 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -2013,6 +2013,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
+               ret = register_netdevice(ndev);
+               if (ret) {
++                      ieee80211_if_free(ndev);
+                       free_netdev(ndev);
+                       return ret;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-mt76-fix-coverity-overrun-call-in-mt76_get_txpo.patch b/queue-5.10/wifi-mt76-fix-coverity-overrun-call-in-mt76_get_txpo.patch
new file mode 100644 (file)
index 0000000..3e6a97b
--- /dev/null
@@ -0,0 +1,44 @@
+From 0bf47e5f595ff05061b2103ba7ca86cbdd1deb5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Nov 2022 10:35:37 +0800
+Subject: wifi: mt76: fix coverity overrun-call in mt76_get_txpower()
+
+From: Deren Wu <deren.wu@mediatek.com>
+
+[ Upstream commit 03dd0d49de7db680a856fa566963bb8421f46368 ]
+
+Make sure the nss is valid for nss_delta array. Return zero
+if the index is invalid.
+
+Coverity message:
+Event overrun-call: Overrunning callee's array of size 4 by passing
+argument "n_chains" (which evaluates to 15) in call to
+"mt76_tx_power_nss_delta".
+int delta = mt76_tx_power_nss_delta(n_chains);
+
+Fixes: 07cda406308b ("mt76: fix rounding issues on converting per-chain and combined txpower")
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt76.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
+index a5be66de1cff..5a8060790a61 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76.h
+@@ -884,8 +884,9 @@ static inline bool mt76_is_skb_pktid(u8 pktid)
+ static inline u8 mt76_tx_power_nss_delta(u8 nss)
+ {
+       static const u8 nss_delta[4] = { 0, 6, 9, 12 };
++      u8 idx = nss - 1;
+-      return nss_delta[nss - 1];
++      return (idx < ARRAY_SIZE(nss_delta)) ? nss_delta[idx] : 0;
+ }
+ static inline bool mt76_testmode_enabled(struct mt76_dev *dev)
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-rsi-fix-handling-of-802.3-eapol-frames-sent-via.patch b/queue-5.10/wifi-rsi-fix-handling-of-802.3-eapol-frames-sent-via.patch
new file mode 100644 (file)
index 0000000..b92320f
--- /dev/null
@@ -0,0 +1,92 @@
+From 6a28949fbad179689095a0e6a7a30538479ac1c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 17:33:39 +0100
+Subject: wifi: rsi: Fix handling of 802.3 EAPOL frames sent via control port
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit b8f6efccbb9dc0ff5dee7e20d69a4747298ee603 ]
+
+When using wpa_supplicant v2.10, this driver is no longer able to
+associate with any AP and fails in the EAPOL 4-way handshake while
+sending the 2/4 message to the AP. The problem is not present in
+wpa_supplicant v2.9 or older. The problem stems from HostAP commit
+144314eaa ("wpa_supplicant: Send EAPOL frames over nl80211 where available")
+which changes the way EAPOL frames are sent, from them being send
+at L2 frames to them being sent via nl80211 control port.
+
+An EAPOL frame sent as L2 frame is passed to the WiFi driver with
+skb->protocol ETH_P_PAE, while EAPOL frame sent via nl80211 control
+port has skb->protocol set to ETH_P_802_3 . The later happens in
+ieee80211_tx_control_port(), where the EAPOL frame is encapsulated
+into 802.3 frame.
+
+The rsi_91x driver handles ETH_P_PAE EAPOL frames as high-priority
+frames and sends them via highest-priority transmit queue, while
+the ETH_P_802_3 frames are sent as regular frames. The EAPOL 4-way
+handshake frames must be sent as highest-priority, otherwise the
+4-way handshake times out.
+
+Therefore, to fix this problem, inspect the skb control flags and
+if flag IEEE80211_TX_CTRL_PORT_CTRL_PROTO is set, assume this is
+an EAPOL frame and transmit the frame via high-priority queue just
+like other ETH_P_PAE frames.
+
+Fixes: 0eb42586cf87 ("rsi: data packet descriptor enhancements")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221104163339.227432-1-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/rsi/rsi_91x_core.c | 4 +++-
+ drivers/net/wireless/rsi/rsi_91x_hal.c  | 6 +++++-
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
+index 9c4c58557248..b7fa03813da1 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_core.c
++++ b/drivers/net/wireless/rsi/rsi_91x_core.c
+@@ -466,7 +466,9 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
+                                                             tid, 0);
+                       }
+               }
+-              if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
++
++              if (IEEE80211_SKB_CB(skb)->control.flags &
++                  IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
+                       q_num = MGMT_SOFT_Q;
+                       skb->priority = q_num;
+               }
+diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
+index dca81a4bbdd7..30d2eccbcadd 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
++++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
+@@ -162,12 +162,16 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
+       u8 header_size;
+       u8 vap_id = 0;
+       u8 dword_align_bytes;
++      bool tx_eapol;
+       u16 seq_num;
+       info = IEEE80211_SKB_CB(skb);
+       vif = info->control.vif;
+       tx_params = (struct skb_info *)info->driver_data;
++      tx_eapol = IEEE80211_SKB_CB(skb)->control.flags &
++                 IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
++
+       header_size = FRAME_DESC_SZ + sizeof(struct rsi_xtended_desc);
+       if (header_size > skb_headroom(skb)) {
+               rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
+@@ -231,7 +235,7 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
+               }
+       }
+-      if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
++      if (tx_eapol) {
+               rsi_dbg(INFO_ZONE, "*** Tx EAPOL ***\n");
+               data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-rtl8xxxu-add-__packed-to-struct-rtl8723bu_c2h.patch b/queue-5.10/wifi-rtl8xxxu-add-__packed-to-struct-rtl8723bu_c2h.patch
new file mode 100644 (file)
index 0000000..ca527ff
--- /dev/null
@@ -0,0 +1,41 @@
+From c093875967ded430ab2407d0babc255746fa1236 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 16:13:57 +0200
+Subject: wifi: rtl8xxxu: Add __packed to struct rtl8723bu_c2h
+
+From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+
+[ Upstream commit dd469a754afdb782ba3033cee102147493dc39f4 ]
+
+This struct is used to access a sequence of bytes received from the
+wifi chip. It must not have any padding bytes between the members.
+
+This doesn't change anything on my system, possibly because currently
+none of the members need more than byte alignment.
+
+Fixes: b2b43b7837ba ("rtl8xxxu: Initial functionality to handle C2H events for 8723bu")
+Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/1a270918-da22-ff5f-29fc-7855f740c5ba@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+index b28fa0c4d180..0ed4d67308d7 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+@@ -1190,7 +1190,7 @@ struct rtl8723bu_c2h {
+                       u8 bw;
+               } __packed ra_report;
+       };
+-};
++} __packed;
+ struct rtl8xxxu_fileops;
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-rtl8xxxu-fix-reading-the-vendor-of-combo-chips.patch b/queue-5.10/wifi-rtl8xxxu-fix-reading-the-vendor-of-combo-chips.patch
new file mode 100644 (file)
index 0000000..3e54daa
--- /dev/null
@@ -0,0 +1,83 @@
+From ce6d4fcdc0dcd9f643c5e2491eb7d81a93e078fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Oct 2022 13:56:09 +0300
+Subject: wifi: rtl8xxxu: Fix reading the vendor of combo chips
+
+From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+
+[ Upstream commit 6f103aeb5e985ac08f3a4a049a2c17294f40cff9 ]
+
+The wifi + bluetooth combo chips (RTL8723AU and RTL8723BU) read the
+chip vendor from the wrong register because the val32 variable gets
+overwritten. Add one more variable to avoid this.
+
+This had no real effect on RTL8723BU. It may have had an effect on
+RTL8723AU.
+
+Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)")
+Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/24af8024-2f07-552b-93d8-38823d8e3cb0@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c    | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index e34cd6fed7e8..43898f105bb7 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -1607,18 +1607,18 @@ static void rtl8xxxu_print_chipinfo(struct rtl8xxxu_priv *priv)
+ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+ {
+       struct device *dev = &priv->udev->dev;
+-      u32 val32, bonding;
++      u32 val32, bonding, sys_cfg;
+       u16 val16;
+-      val32 = rtl8xxxu_read32(priv, REG_SYS_CFG);
+-      priv->chip_cut = (val32 & SYS_CFG_CHIP_VERSION_MASK) >>
++      sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG);
++      priv->chip_cut = (sys_cfg & SYS_CFG_CHIP_VERSION_MASK) >>
+               SYS_CFG_CHIP_VERSION_SHIFT;
+-      if (val32 & SYS_CFG_TRP_VAUX_EN) {
++      if (sys_cfg & SYS_CFG_TRP_VAUX_EN) {
+               dev_info(dev, "Unsupported test chip\n");
+               return -ENOTSUPP;
+       }
+-      if (val32 & SYS_CFG_BT_FUNC) {
++      if (sys_cfg & SYS_CFG_BT_FUNC) {
+               if (priv->chip_cut >= 3) {
+                       sprintf(priv->chip_name, "8723BU");
+                       priv->rtl_chip = RTL8723B;
+@@ -1640,7 +1640,7 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+               if (val32 & MULTI_GPS_FUNC_EN)
+                       priv->has_gps = 1;
+               priv->is_multi_func = 1;
+-      } else if (val32 & SYS_CFG_TYPE_ID) {
++      } else if (sys_cfg & SYS_CFG_TYPE_ID) {
+               bonding = rtl8xxxu_read32(priv, REG_HPON_FSM);
+               bonding &= HPON_FSM_BONDING_MASK;
+               if (priv->fops->tx_desc_size ==
+@@ -1688,7 +1688,7 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+       case RTL8188E:
+       case RTL8192E:
+       case RTL8723B:
+-              switch (val32 & SYS_CFG_VENDOR_EXT_MASK) {
++              switch (sys_cfg & SYS_CFG_VENDOR_EXT_MASK) {
+               case SYS_CFG_VENDOR_ID_TSMC:
+                       sprintf(priv->chip_vendor, "TSMC");
+                       break;
+@@ -1705,7 +1705,7 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+               }
+               break;
+       default:
+-              if (val32 & SYS_CFG_VENDOR_ID) {
++              if (sys_cfg & SYS_CFG_VENDOR_ID) {
+                       sprintf(priv->chip_vendor, "UMC");
+                       priv->vendor_umc = 1;
+               } else {
+-- 
+2.35.1
+
diff --git a/queue-5.10/wifi-rtl8xxxu-fix-the-channel-width-reporting.patch b/queue-5.10/wifi-rtl8xxxu-fix-the-channel-width-reporting.patch
new file mode 100644 (file)
index 0000000..7fdeee0
--- /dev/null
@@ -0,0 +1,62 @@
+From 15bdc7772215f37ca8b82487e01fc0cac5b43340 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 16:15:08 +0200
+Subject: wifi: rtl8xxxu: Fix the channel width reporting
+
+From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+
+[ Upstream commit 76c16af2cb10282274596e21add2c9f0b95c941b ]
+
+The gen 2 chips RTL8192EU and RTL8188FU periodically send the driver
+reports about the TX rate, and the driver passes these reports to
+sta_statistics. The reports from RTL8192EU may or may not include the
+channel width. The reports from RTL8188FU do not include it.
+
+Only access the c2h->ra_report.bw field if the report (skb) is big
+enough.
+
+The other problem fixed here is that the code was actually never
+changing the channel width initially reported by
+rtl8xxxu_bss_info_changed because the value of RATE_INFO_BW_20 is 0.
+
+Fixes: 0985d3a410ac ("rtl8xxxu: Feed current txrate information for mac80211")
+Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/5b41f1ae-72e7-6b7a-2459-b736399a1c40@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index 43898f105bb7..9a12f1d38007 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -5520,7 +5520,6 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
+                       rarpt->txrate.flags = 0;
+                       rate = c2h->ra_report.rate;
+                       sgi = c2h->ra_report.sgi;
+-                      bw = c2h->ra_report.bw;
+                       if (rate < DESC_RATE_MCS0) {
+                               rarpt->txrate.legacy =
+@@ -5537,8 +5536,13 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
+                                               RATE_INFO_FLAGS_SHORT_GI;
+                               }
+-                              if (bw == RATE_INFO_BW_20)
+-                                      rarpt->txrate.bw |= RATE_INFO_BW_20;
++                              if (skb->len >= offsetofend(typeof(*c2h), ra_report.bw)) {
++                                      if (c2h->ra_report.bw == RTL8XXXU_CHANNEL_WIDTH_40)
++                                              bw = RATE_INFO_BW_40;
++                                      else
++                                              bw = RATE_INFO_BW_20;
++                                      rarpt->txrate.bw = bw;
++                              }
+                       }
+                       bit_rate = cfg80211_calculate_bitrate(&rarpt->txrate);
+                       rarpt->bit_rate = bit_rate;
+-- 
+2.35.1
+
diff --git a/queue-5.10/x86-hyperv-remove-unregister-syscore-call-from-hyper.patch b/queue-5.10/x86-hyperv-remove-unregister-syscore-call-from-hyper.patch
new file mode 100644 (file)
index 0000000..0d1108f
--- /dev/null
@@ -0,0 +1,48 @@
+From a0783138887b74436eca2c645b76a74079e5256d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Nov 2022 22:14:51 -0800
+Subject: x86/hyperv: Remove unregister syscore call from Hyper-V cleanup
+
+From: Gaurav Kohli <gauravkohli@linux.microsoft.com>
+
+[ Upstream commit 32c97d980e2eef25465d453f2956a9ca68926a3c ]
+
+Hyper-V cleanup code comes under panic path where preemption and irq
+is already disabled. So calling of unregister_syscore_ops might schedule
+out the thread even for the case where mutex lock is free.
+hyperv_cleanup
+       unregister_syscore_ops
+                       mutex_lock(&syscore_ops_lock)
+                               might_sleep
+Here might_sleep might schedule out this thread, where voluntary preemption
+config is on and this thread will never comes back. And also this was added
+earlier to maintain the symmetry which is not required as this can comes
+during crash shutdown path only.
+
+To prevent the same, removing unregister_syscore_ops function call.
+
+Signed-off-by: Gaurav Kohli <gauravkohli@linux.microsoft.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/1669443291-2575-1-git-send-email-gauravkohli@linux.microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/hyperv/hv_init.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+index 01860c0d324d..70fd21ebb9d5 100644
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -453,8 +453,6 @@ void hyperv_cleanup(void)
+ {
+       union hv_x64_msr_hypercall_contents hypercall_msr;
+-      unregister_syscore_ops(&hv_syscore_ops);
+-
+       /* Reset our OS id */
+       wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
+-- 
+2.35.1
+
diff --git a/queue-5.10/x86-xen-fix-memory-leak-in-xen_init_lock_cpu.patch b/queue-5.10/x86-xen-fix-memory-leak-in-xen_init_lock_cpu.patch
new file mode 100644 (file)
index 0000000..68ed6f9
--- /dev/null
@@ -0,0 +1,64 @@
+From d1e9feff0837febff03665b0920e8fd549f8b792 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 23:58:58 +0800
+Subject: x86/xen: Fix memory leak in xen_init_lock_cpu()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit ca84ce153d887b1dc8b118029976cc9faf2a9b40 ]
+
+In xen_init_lock_cpu(), the @name has allocated new string by kasprintf(),
+if bind_ipi_to_irqhandler() fails, it should be freed, otherwise may lead
+to a memory leak issue, fix it.
+
+Fixes: 2d9e1e2f58b5 ("xen: implement Xen-specific spinlocks")
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/20221123155858.11382-3-xiujianfeng@huawei.com
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/xen/spinlock.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
+index 043c73dfd2c9..5c6fc16e4b92 100644
+--- a/arch/x86/xen/spinlock.c
++++ b/arch/x86/xen/spinlock.c
+@@ -75,6 +75,7 @@ void xen_init_lock_cpu(int cpu)
+            cpu, per_cpu(lock_kicker_irq, cpu));
+       name = kasprintf(GFP_KERNEL, "spinlock%d", cpu);
++      per_cpu(irq_name, cpu) = name;
+       irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR,
+                                    cpu,
+                                    dummy_handler,
+@@ -85,7 +86,6 @@ void xen_init_lock_cpu(int cpu)
+       if (irq >= 0) {
+               disable_irq(irq); /* make sure it's never delivered */
+               per_cpu(lock_kicker_irq, cpu) = irq;
+-              per_cpu(irq_name, cpu) = name;
+       }
+       printk("cpu %d spinlock event irq %d\n", cpu, irq);
+@@ -98,6 +98,8 @@ void xen_uninit_lock_cpu(int cpu)
+       if (!xen_pvspin)
+               return;
++      kfree(per_cpu(irq_name, cpu));
++      per_cpu(irq_name, cpu) = NULL;
+       /*
+        * When booting the kernel with 'mitigations=auto,nosmt', the secondary
+        * CPUs are not activated, and lock_kicker_irq is not initialized.
+@@ -108,8 +110,6 @@ void xen_uninit_lock_cpu(int cpu)
+       unbind_from_irqhandler(irq, NULL);
+       per_cpu(lock_kicker_irq, cpu) = -1;
+-      kfree(per_cpu(irq_name, cpu));
+-      per_cpu(irq_name, cpu) = NULL;
+ }
+ PV_CALLEE_SAVE_REGS_THUNK(xen_vcpu_stolen);
+-- 
+2.35.1
+
diff --git a/queue-5.10/x86-xen-fix-memory-leak-in-xen_smp_intr_init-_pv.patch b/queue-5.10/x86-xen-fix-memory-leak-in-xen_smp_intr_init-_pv.patch
new file mode 100644 (file)
index 0000000..7be0967
--- /dev/null
@@ -0,0 +1,178 @@
+From 18ce06b70d43e27bb0b1fc1d6e8433b19ea11b8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 23:58:57 +0800
+Subject: x86/xen: Fix memory leak in xen_smp_intr_init{_pv}()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 69143f60868b3939ddc89289b29db593b647295e ]
+
+These local variables @{resched|pmu|callfunc...}_name saves the new
+string allocated by kasprintf(), and when bind_{v}ipi_to_irqhandler()
+fails, it goes to the @fail tag, and calls xen_smp_intr_free{_pv}() to
+free resource, however the new string is not saved, which cause a memory
+leak issue. fix it.
+
+Fixes: 9702785a747a ("i386: move xen")
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/20221123155858.11382-2-xiujianfeng@huawei.com
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/xen/smp.c    | 24 ++++++++++++------------
+ arch/x86/xen/smp_pv.c | 12 ++++++------
+ 2 files changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
+index c1b2f764b29a..cdec892b28e2 100644
+--- a/arch/x86/xen/smp.c
++++ b/arch/x86/xen/smp.c
+@@ -32,30 +32,30 @@ static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id)
+ void xen_smp_intr_free(unsigned int cpu)
+ {
++      kfree(per_cpu(xen_resched_irq, cpu).name);
++      per_cpu(xen_resched_irq, cpu).name = NULL;
+       if (per_cpu(xen_resched_irq, cpu).irq >= 0) {
+               unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu).irq, NULL);
+               per_cpu(xen_resched_irq, cpu).irq = -1;
+-              kfree(per_cpu(xen_resched_irq, cpu).name);
+-              per_cpu(xen_resched_irq, cpu).name = NULL;
+       }
++      kfree(per_cpu(xen_callfunc_irq, cpu).name);
++      per_cpu(xen_callfunc_irq, cpu).name = NULL;
+       if (per_cpu(xen_callfunc_irq, cpu).irq >= 0) {
+               unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu).irq, NULL);
+               per_cpu(xen_callfunc_irq, cpu).irq = -1;
+-              kfree(per_cpu(xen_callfunc_irq, cpu).name);
+-              per_cpu(xen_callfunc_irq, cpu).name = NULL;
+       }
++      kfree(per_cpu(xen_debug_irq, cpu).name);
++      per_cpu(xen_debug_irq, cpu).name = NULL;
+       if (per_cpu(xen_debug_irq, cpu).irq >= 0) {
+               unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu).irq, NULL);
+               per_cpu(xen_debug_irq, cpu).irq = -1;
+-              kfree(per_cpu(xen_debug_irq, cpu).name);
+-              per_cpu(xen_debug_irq, cpu).name = NULL;
+       }
++      kfree(per_cpu(xen_callfuncsingle_irq, cpu).name);
++      per_cpu(xen_callfuncsingle_irq, cpu).name = NULL;
+       if (per_cpu(xen_callfuncsingle_irq, cpu).irq >= 0) {
+               unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu).irq,
+                                      NULL);
+               per_cpu(xen_callfuncsingle_irq, cpu).irq = -1;
+-              kfree(per_cpu(xen_callfuncsingle_irq, cpu).name);
+-              per_cpu(xen_callfuncsingle_irq, cpu).name = NULL;
+       }
+ }
+@@ -65,6 +65,7 @@ int xen_smp_intr_init(unsigned int cpu)
+       char *resched_name, *callfunc_name, *debug_name;
+       resched_name = kasprintf(GFP_KERNEL, "resched%d", cpu);
++      per_cpu(xen_resched_irq, cpu).name = resched_name;
+       rc = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR,
+                                   cpu,
+                                   xen_reschedule_interrupt,
+@@ -74,9 +75,9 @@ int xen_smp_intr_init(unsigned int cpu)
+       if (rc < 0)
+               goto fail;
+       per_cpu(xen_resched_irq, cpu).irq = rc;
+-      per_cpu(xen_resched_irq, cpu).name = resched_name;
+       callfunc_name = kasprintf(GFP_KERNEL, "callfunc%d", cpu);
++      per_cpu(xen_callfunc_irq, cpu).name = callfunc_name;
+       rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_VECTOR,
+                                   cpu,
+                                   xen_call_function_interrupt,
+@@ -86,10 +87,10 @@ int xen_smp_intr_init(unsigned int cpu)
+       if (rc < 0)
+               goto fail;
+       per_cpu(xen_callfunc_irq, cpu).irq = rc;
+-      per_cpu(xen_callfunc_irq, cpu).name = callfunc_name;
+       if (!xen_fifo_events) {
+               debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu);
++              per_cpu(xen_debug_irq, cpu).name = debug_name;
+               rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu,
+                                            xen_debug_interrupt,
+                                            IRQF_PERCPU | IRQF_NOBALANCING,
+@@ -97,10 +98,10 @@ int xen_smp_intr_init(unsigned int cpu)
+               if (rc < 0)
+                       goto fail;
+               per_cpu(xen_debug_irq, cpu).irq = rc;
+-              per_cpu(xen_debug_irq, cpu).name = debug_name;
+       }
+       callfunc_name = kasprintf(GFP_KERNEL, "callfuncsingle%d", cpu);
++      per_cpu(xen_callfuncsingle_irq, cpu).name = callfunc_name;
+       rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR,
+                                   cpu,
+                                   xen_call_function_single_interrupt,
+@@ -110,7 +111,6 @@ int xen_smp_intr_init(unsigned int cpu)
+       if (rc < 0)
+               goto fail;
+       per_cpu(xen_callfuncsingle_irq, cpu).irq = rc;
+-      per_cpu(xen_callfuncsingle_irq, cpu).name = callfunc_name;
+       return 0;
+diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c
+index 35b6d15d874d..64873937cd1d 100644
+--- a/arch/x86/xen/smp_pv.c
++++ b/arch/x86/xen/smp_pv.c
+@@ -98,18 +98,18 @@ asmlinkage __visible void cpu_bringup_and_idle(void)
+ void xen_smp_intr_free_pv(unsigned int cpu)
+ {
++      kfree(per_cpu(xen_irq_work, cpu).name);
++      per_cpu(xen_irq_work, cpu).name = NULL;
+       if (per_cpu(xen_irq_work, cpu).irq >= 0) {
+               unbind_from_irqhandler(per_cpu(xen_irq_work, cpu).irq, NULL);
+               per_cpu(xen_irq_work, cpu).irq = -1;
+-              kfree(per_cpu(xen_irq_work, cpu).name);
+-              per_cpu(xen_irq_work, cpu).name = NULL;
+       }
++      kfree(per_cpu(xen_pmu_irq, cpu).name);
++      per_cpu(xen_pmu_irq, cpu).name = NULL;
+       if (per_cpu(xen_pmu_irq, cpu).irq >= 0) {
+               unbind_from_irqhandler(per_cpu(xen_pmu_irq, cpu).irq, NULL);
+               per_cpu(xen_pmu_irq, cpu).irq = -1;
+-              kfree(per_cpu(xen_pmu_irq, cpu).name);
+-              per_cpu(xen_pmu_irq, cpu).name = NULL;
+       }
+ }
+@@ -119,6 +119,7 @@ int xen_smp_intr_init_pv(unsigned int cpu)
+       char *callfunc_name, *pmu_name;
+       callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu);
++      per_cpu(xen_irq_work, cpu).name = callfunc_name;
+       rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR,
+                                   cpu,
+                                   xen_irq_work_interrupt,
+@@ -128,10 +129,10 @@ int xen_smp_intr_init_pv(unsigned int cpu)
+       if (rc < 0)
+               goto fail;
+       per_cpu(xen_irq_work, cpu).irq = rc;
+-      per_cpu(xen_irq_work, cpu).name = callfunc_name;
+       if (is_xen_pmu) {
+               pmu_name = kasprintf(GFP_KERNEL, "pmu%d", cpu);
++              per_cpu(xen_pmu_irq, cpu).name = pmu_name;
+               rc = bind_virq_to_irqhandler(VIRQ_XENPMU, cpu,
+                                            xen_pmu_irq_handler,
+                                            IRQF_PERCPU|IRQF_NOBALANCING,
+@@ -139,7 +140,6 @@ int xen_smp_intr_init_pv(unsigned int cpu)
+               if (rc < 0)
+                       goto fail;
+               per_cpu(xen_pmu_irq, cpu).irq = rc;
+-              per_cpu(xen_pmu_irq, cpu).name = pmu_name;
+       }
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.10/xen-privcmd-fix-a-possible-warning-in-privcmd_ioctl_.patch b/queue-5.10/xen-privcmd-fix-a-possible-warning-in-privcmd_ioctl_.patch
new file mode 100644 (file)
index 0000000..c94a772
--- /dev/null
@@ -0,0 +1,46 @@
+From 24ee8ae19b52e8ecd784d11965da8ef3a62d28ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Nov 2022 21:07:45 -0800
+Subject: xen/privcmd: Fix a possible warning in privcmd_ioctl_mmap_resource()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit 8b997b2bb2c53b76a6db6c195930e9ab8e4b0c79 ]
+
+As 'kdata.num' is user-controlled data, if user tries to allocate
+memory larger than(>=) MAX_ORDER, then kcalloc() will fail, it
+creates a stack trace and messes up dmesg with a warning.
+
+Call trace:
+-> privcmd_ioctl
+--> privcmd_ioctl_mmap_resource
+
+Add __GFP_NOWARN in order to avoid too large allocation warning.
+This is detected by static analysis using smatch.
+
+Fixes: 3ad0876554ca ("xen/privcmd: add IOCTL_PRIVCMD_MMAP_RESOURCE")
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/20221126050745.778967-1-harshit.m.mogalapalli@oracle.com
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/privcmd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
+index cd5f2f09468e..28537a1a0e0b 100644
+--- a/drivers/xen/privcmd.c
++++ b/drivers/xen/privcmd.c
+@@ -760,7 +760,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file,
+               goto out;
+       }
+-      pfns = kcalloc(kdata.num, sizeof(*pfns), GFP_KERNEL);
++      pfns = kcalloc(kdata.num, sizeof(*pfns), GFP_KERNEL | __GFP_NOWARN);
+       if (!pfns) {
+               rc = -ENOMEM;
+               goto out;
+-- 
+2.35.1
+
diff --git a/queue-5.10/xprtrdma-fix-regbuf-data-not-freed-in-rpcrdma_req_cr.patch b/queue-5.10/xprtrdma-fix-regbuf-data-not-freed-in-rpcrdma_req_cr.patch
new file mode 100644 (file)
index 0000000..cfc2434
--- /dev/null
@@ -0,0 +1,36 @@
+From d4c377ba6b855f0b3e907682a9aa823622a97463 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Nov 2022 15:34:29 +0800
+Subject: xprtrdma: Fix regbuf data not freed in rpcrdma_req_create()
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+[ Upstream commit 9181f40fb2952fd59ecb75e7158620c9c669eee3 ]
+
+If rdma receive buffer allocate failed, should call rpcrdma_regbuf_free()
+to free the send buffer, otherwise, the buffer data will be leaked.
+
+Fixes: bb93a1ae2bf4 ("xprtrdma: Allocate req's regbufs at xprt create time")
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/xprtrdma/verbs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
+index dcc1992b14d7..338b06de86d1 100644
+--- a/net/sunrpc/xprtrdma/verbs.c
++++ b/net/sunrpc/xprtrdma/verbs.c
+@@ -866,7 +866,7 @@ struct rpcrdma_req *rpcrdma_req_create(struct rpcrdma_xprt *r_xprt, size_t size,
+       return req;
+ out3:
+-      kfree(req->rl_sendbuf);
++      rpcrdma_regbuf_free(req->rl_sendbuf);
+ out2:
+       kfree(req);
+ out1:
+-- 
+2.35.1
+